<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
	<title>
    SQLAlchemy Documentation
</title>
	
    <link rel="stylesheet" href="style.css"></link>
    <link rel="stylesheet" href="docs.css"></link>
    <link href="syntaxhighlight.css" rel="stylesheet" type="text/css"></link>
    <script src="scripts.js"></script>



</head>
<body>








<div id="topanchor"><a name="top">&nbsp;</a></div>


<h1>SQLAlchemy 0.4 Documentation</h1>

<div id="pagecontrol"><a href="index.html">Multiple Pages</a> | <a href="documentation.html">One Page</a></div>

<div class="versionheader">Version: 0.4.8   Last Updated: 10/12/08 13:33:19</div>







	<div class="topnav">

	<a name="table_of_contents"></a>
	<h3>Table of Contents</h3>
	&nbsp;&nbsp;
	<a href="#full_index" class="totoc">(view full table)</a>
	<br/><br/>
	
    <ul>
        
        <li><a style="" href="#overview">Overview / Installation</a></li>

        
        <li><a style="" href="#datamapping">Object Relational Tutorial</a></li>

        
        <li><a style="" href="#sql">SQL Expression Language Tutorial</a></li>

        
        <li><a style="" href="#advdatamapping">Mapper Configuration</a></li>

        
        <li><a style="" href="#unitofwork">Using the Session</a></li>

        
        <li><a style="" href="#dbengine">Database Engines</a></li>

        
        <li><a style="" href="#metadata">Database Meta Data</a></li>

        
        <li><a style="" href="#types">The Types System</a></li>

        
        <li><a style="" href="#pooling">Connection Pooling</a></li>

        
        <li><a style="" href="#plugins">Plugins</a></li>

        
        <li><a style="" href="docstrings.html">API Documentation</a></li>

        
        <li><a style="" href="#copyright">Appendix:  Copyright</a></li>

    </ul>


	<a name="full_index"></a>
	<h3>Table of Contents: Full</h3>
	&nbsp;&nbsp;
	<a href="#table_of_contents" class="totoc">(view brief table)</a>

	
    <ul>
        
        <li><a style="" href="#overview">Overview / Installation</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#overview_overview">Overview</a></li>

        
        <li><a style="" href="#overview_tutorials">Tutorials</a></li>

        
        <li><a style="" href="#overview_reference">Reference Documentation</a></li>

        
        <li><a style="" href="#overview_sqlalchemy">Installing SQLAlchemy</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#overview_sqlalchemy_dbms">Installing a Database API</a></li>

        
        <li><a style="" href="#overview_sqlalchemy_checking">Checking the Installed SQLAlchemy Version</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#overview_migration">0.3 to 0.4 Migration</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#overview_migration_imports">ORM Package is now sqlalchemy.orm</a></li>

        
        <li><a style="" href="#overview_migration_metadata">BoundMetaData is now MetaData</a></li>

        
        <li><a style="" href="#overview_migration_global">"Magic" Global MetaData removed</a></li>

        
        <li><a style="" href="#overview_migration_generative">Some existing select() methods become generative</a></li>

        
        <li><a style="" href="#overview_migration_collection">collection_class behavior is changed</a></li>

        
        <li><a style="" href="#overview_migration_bind">All "engine", "bind_to", "connectable" Keyword Arguments Changed to "bind"</a></li>

        
        <li><a style="" href="#overview_migration_type">All "type" Keyword Arguments Changed to "type_"</a></li>

        
        <li><a style="" href="#overview_migration_mapper">Mapper Extensions must return EXT_CONTINUE to continue execution to the next mapper</a></li>

    </ul>

	        </li>
    </ul>

	        </li>
        
        <li><a style="" href="#datamapping">Object Relational Tutorial</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#datamapping_version">Version Check</a></li>

        
        <li><a style="" href="#datamapping_connecting">Connecting</a></li>

        
        <li><a style="" href="#datamapping_tables">Define and Create a Table</a></li>

        
        <li><a style="" href="#datamapping_mapping">Define a Python Class to be Mapped</a></li>

        
        <li><a style="" href="#datamapping_setting">Setting up the Mapping</a></li>

        
        <li><a style="" href="#datamapping_too">Too Verbose ?  There are alternatives</a></li>

        
        <li><a style="" href="#datamapping_creating">Creating a Session</a></li>

        
        <li><a style="" href="#datamapping_saving">Saving Objects</a></li>

        
        <li><a style="" href="#datamapping_querying">Querying</a></li>

        
        <li><a style="" href="#datamapping_onetomany">Building a One-to-Many Relation</a></li>

        
        <li><a style="" href="#datamapping_relation_backref">Working with Related Objects and Backreferences</a></li>

        
        <li><a style="" href="#datamapping_joins">Querying with Joins</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#datamapping_joins_relation">Relation Operators</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#datamapping_deleting">Deleting</a></li>

        
        <li><a style="" href="#datamapping_manytomany">Building a Many To Many Relation</a></li>

        
        <li><a style="" href="#datamapping_further">Further Reference</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#sql">SQL Expression Language Tutorial</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#sql_version">Version Check</a></li>

        
        <li><a style="" href="#sql_connecting">Connecting</a></li>

        
        <li><a style="" href="#sql_tables">Define and Create Tables</a></li>

        
        <li><a style="" href="#sql_insert">Insert Expressions</a></li>

        
        <li><a style="" href="#sql_executing">Executing</a></li>

        
        <li><a style="" href="#sql_execmany">Executing Multiple Statements</a></li>

        
        <li><a style="" href="#sql_connectionless">Connectionless / Implicit Execution</a></li>

        
        <li><a style="" href="#sql_selecting">Selecting</a></li>

        
        <li><a style="" href="#sql_operators">Operators</a></li>

        
        <li><a style="" href="#sql_conjunctions">Conjunctions</a></li>

        
        <li><a style="" href="#sql_text">Using Text</a></li>

        
        <li><a style="" href="#sql_aliases">Using Aliases</a></li>

        
        <li><a style="" href="#sql_joins">Using Joins</a></li>

        
        <li><a style="" href="#sql_transform">Intro to Generative Selects and Transformations</a></li>

        
        <li><a style="" href="#sql_everythingelse">Everything Else</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#sql_everythingelse_bindparams">Bind Parameter Objects</a></li>

        
        <li><a style="" href="#sql_everythingelse_functions">Functions</a></li>

        
        <li><a style="" href="#sql_everythingelse_unions">Unions and Other Set Operations</a></li>

        
        <li><a style="" href="#sql_everythingelse_scalar">Scalar Selects</a></li>

        
        <li><a style="" href="#sql_everythingelse_correlated">Correlated Subqueries</a></li>

        
        <li><a style="" href="#sql_everythingelse_ordering">Ordering, Grouping, Limiting, Offset...ing...</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#sql_update">Updates</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#sql_update_correlated">Correlated Updates</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#sql_delete">Deletes</a></li>

        
        <li><a style="" href="#sql_reference">Further Reference</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping">Mapper Configuration</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_mapper">Mapper Configuration</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_mapper_columns">Customizing Column Properties</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_deferred">Deferred Column Loading</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_expressions">SQL Expressions as Mapped Attributes</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_overriding">Overriding Attribute Behavior with Synonyms</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_composite">Composite Column Types</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_orderby">Controlling Ordering</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_inheritance">Mapping Class Inheritance Hierarchies</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_mapper_inheritance_joined">Joined Table Inheritance</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_mapper_inheritance_joined_querying">Polymorphic Querying Strategies</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_inheritance_joined_optimizing">Optimizing Joined Table Loads</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_mapper_inheritance_single">Single Table Inheritance</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_inheritance_concrete">Concrete Table Inheritance</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_inheritance_relations">Using Relations with Inheritance</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_mapper_joins">Mapping a Class against Multiple Tables</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_selects">Mapping a Class against Arbitrary Selects</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_multiple">Multiple Mappers for One Class</a></li>

        
        <li><a style="" href="#advdatamapping_mapper_extending">Extending Mapper</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_relation">Relation Configuration</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_relation_patterns">Basic Relational Patterns</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_relation_patterns_onetomany">One To Many</a></li>

        
        <li><a style="" href="#advdatamapping_relation_patterns_manytoone">Many To One</a></li>

        
        <li><a style="" href="#advdatamapping_relation_patterns_onetoone">One To One</a></li>

        
        <li><a style="" href="#advdatamapping_relation_patterns_manytomany">Many To Many</a></li>

        
        <li><a style="" href="#advdatamapping_relation_patterns_association">Association Object</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_relation_selfreferential">Adjacency List Relationships</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_relation_selfreferential_query">Self-Referential Query Strategies</a></li>

        
        <li><a style="" href="#advdatamapping_relation_selfreferential_eagerloading">Configuring Eager Loading</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_relation_customjoin">Specifying Alternate Join Conditions to relation()</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_relation_customjoin_fks">Specifying Foreign Keys</a></li>

        
        <li><a style="" href="#advdatamapping_relation_customjoin_properties">Building Query-Enabled Properties</a></li>

        
        <li><a style="" href="#advdatamapping_relation_customjoin_multiplejoin">Multiple Relations against the Same Parent/Child</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_relation_collections">Alternate Collection Implementations</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_relation_collections_custom">Custom Collection Implementations</a></li>

        
        <li><a style="" href="#advdatamapping_relation_collections_decorators">Annotating Custom Collections via Decorators</a></li>

        
        <li><a style="" href="#advdatamapping_relation_collections_dictcollections">Dictionary-Based Collections</a></li>

        
        <li><a style="" href="#advdatamapping_relation_collections_adv_collections">Instrumentation and Custom Types</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_relation_strategies">Configuring Loader Strategies: Lazy Loading, Eager Loading</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_relation_strategies_combining">Combining Eager Loads with Statement/Result Set Queries</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_relation_largecollections">Working with Large Collections</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#advdatamapping_relation_largecollections_dynamic">Dynamic Relation Loaders</a></li>

        
        <li><a style="" href="#advdatamapping_relation_largecollections_noload">Setting Noload</a></li>

        
        <li><a style="" href="#advdatamapping_relation_largecollections_passivedelete">Using Passive Deletes</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#advdatamapping_relation_mutablepks">Mutable Primary Keys / Update Cascades</a></li>

    </ul>

	        </li>
    </ul>

	        </li>
        
        <li><a style="" href="#unitofwork">Using the Session</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#unitofwork_what">What does the Session do ?</a></li>

        
        <li><a style="" href="#unitofwork_getting">Getting a Session</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#unitofwork_getting_sessionmaker">Using a sessionmaker() Configuration</a></li>

        
        <li><a style="" href="#unitofwork_getting_binding">Binding Session to an Engine or Connection</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#unitofwork_getting_binding_connection">Binding Session to a Connection</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#unitofwork_getting_createsession">Using create_session()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#unitofwork_using">Using the Session</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#unitofwork_using_states">Quickie Intro to Object States</a></li>

        
        <li><a style="" href="#unitofwork_using_faq">Frequently Asked Questions</a></li>

        
        <li><a style="" href="#unitofwork_using_attributes">Session Attributes</a></li>

        
        <li><a style="" href="#unitofwork_using_querying">Querying</a></li>

        
        <li><a style="" href="#unitofwork_using_saving">Saving New Instances</a></li>

        
        <li><a style="" href="#unitofwork_using_updating/merging">Updating/Merging Existing Instances</a></li>

        
        <li><a style="" href="#unitofwork_using_deleting">Deleting</a></li>

        
        <li><a style="" href="#unitofwork_using_flushing">Flushing</a></li>

        
        <li><a style="" href="#unitofwork_using_autoflush">Autoflush</a></li>

        
        <li><a style="" href="#unitofwork_using_committing">Committing</a></li>

        
        <li><a style="" href="#unitofwork_using_expunge">Expunge / Clear</a></li>

        
        <li><a style="" href="#unitofwork_using_closing">Closing</a></li>

        
        <li><a style="" href="#unitofwork_using_refreshing">Refreshing / Expiring</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#unitofwork_cascades">Cascades</a></li>

        
        <li><a style="" href="#unitofwork_managing">Managing Transactions</a></li>

        
        <li><a style="" href="#unitofwork_flushsql">Embedding SQL Insert/Update Expressions into a Flush</a></li>

        
        <li><a style="" href="#unitofwork_sql">Using SQL Expressions with Sessions</a></li>

        
        <li><a style="" href="#unitofwork_contextual">Contextual/Thread-local Sessions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#unitofwork_contextual_creating">Creating a Thread-local Context</a></li>

        
        <li><a style="" href="#unitofwork_contextual_lifespan">Lifespan of a Contextual Session</a></li>

        
        <li><a style="" href="#unitofwork_contextual_associating">Associating Classes and Mappers with a Contextual Session</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#unitofwork_contextual_associating_autosave">Auto-Save Behavior with Contextual Session's Mapper</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#unitofwork_contextual_partitioning">Partitioning Strategies</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#unitofwork_contextual_partitioning_vertical">Vertical Partitioning</a></li>

        
        <li><a style="" href="#unitofwork_contextual_partitioning_horizontal">Horizontal Partitioning</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#unitofwork_contextual_extending">Extending Session</a></li>

    </ul>

	        </li>
    </ul>

	        </li>
        
        <li><a style="" href="#dbengine">Database Engines</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#dbengine_supported">Supported Databases</a></li>

        
        <li><a style="" href="#dbengine_establishing">create_engine() URL Arguments</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#dbengine_establishing_custom">Custom DBAPI connect() arguments</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#dbengine_options">Database Engine Options</a></li>

        
        <li><a style="" href="#dbengine_connections">More On Connections</a></li>

        
        <li><a style="" href="#dbengine_transactions">Using Transactions with Connection</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#dbengine_transactions_understanding">Understanding Autocommit</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#dbengine_implicit">Connectionless Execution, Implicit Execution</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#dbengine_implicit_strategies">Using the Threadlocal Execution Strategy</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#dbengine_logging">Configuring Logging</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#metadata">Database Meta Data</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#metadata_tables">Describing Databases with MetaData</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#metadata_tables_binding">Binding MetaData to an Engine or Connection</a></li>

        
        <li><a style="" href="#metadata_tables_reflecting">Reflecting Tables</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#metadata_tables_reflecting_overriding">Overriding Reflected Columns</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#metadata_tables_schema">Specifying the Schema Name</a></li>

        
        <li><a style="" href="#metadata_tables_onupdate">ON UPDATE and ON DELETE</a></li>

        
        <li><a style="" href="#metadata_tables_options">Other Options</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#metadata_creating">Creating and Dropping Database Tables</a></li>

        
        <li><a style="" href="#metadata_defaults">Column Insert/Update Defaults</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#metadata_defaults_preexecute_functions">Pre-Executed Python Functions</a></li>

        
        <li><a style="" href="#metadata_defaults_sqlexpression">Pre-executed and Inline SQL Expressions</a></li>

        
        <li><a style="" href="#metadata_defaults_passive">DDL-Level Defaults</a></li>

        
        <li><a style="" href="#metadata_defaults_sequences">Defining Sequences</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#metadata_constraints">Defining Constraints and Indexes</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#metadata_constraints_unique">UNIQUE Constraint</a></li>

        
        <li><a style="" href="#metadata_constraints_check">CHECK Constraint</a></li>

        
        <li><a style="" href="#metadata_constraints_indexes">Indexes</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#metadata_adapting">Adapting Tables to Alternate Metadata</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#types">The Types System</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#types_standard">Built-in Types</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#types_standard_string">String</a></li>

        
        <li><a style="" href="#types_standard_unicode">Unicode</a></li>

        
        <li><a style="" href="#types_standard_text">Text / UnicodeText</a></li>

        
        <li><a style="" href="#types_standard_numeric">Numeric</a></li>

        
        <li><a style="" href="#types_standard_float">Float</a></li>

        
        <li><a style="" href="#types_standard_datetime/date/time">Datetime/Date/Time</a></li>

        
        <li><a style="" href="#types_standard_interval">Interval</a></li>

        
        <li><a style="" href="#types_standard_binary">Binary</a></li>

        
        <li><a style="" href="#types_standard_boolean">Boolean</a></li>

        
        <li><a style="" href="#types_standard_pickletype">PickleType</a></li>

        
        <li><a style="" href="#types_standard_sqlspecific">SQL-Specific Types</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#types_dialect">Dialect Specific Types</a></li>

        
        <li><a style="" href="#types_custom">Creating your Own Types</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#pooling">Connection Pooling</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#pooling_establishing">Establishing a Transparent Connection Pool</a></li>

        
        <li><a style="" href="#pooling_configuration">Connection Pool Configuration</a></li>

        
        <li><a style="" href="#pooling_custom">Custom Pool Construction</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#plugins">Plugins</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#plugins_declarative">declarative</a></li>

        
        <li><a style="" href="#plugins_associationproxy">associationproxy</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#plugins_associationproxy_simplifying">Simplifying Relations</a></li>

        
        <li><a style="" href="#plugins_associationproxy_simplifying">Simplifying Association Object Relations</a></li>

        
        <li><a style="" href="#plugins_associationproxy_building">Building Complex Views</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="#plugins_orderinglist">orderinglist</a></li>

        
        <li><a style="" href="#plugins_sqlsoup">SqlSoup</a></li>

        
        <li><a style="" href="#plugins_deprecated">Deprecated Extensions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#plugins_deprecated_selectresults">SelectResults</a></li>

        
        <li><a style="" href="#plugins_deprecated_sessioncontext">SessionContext</a></li>

        
        <li><a style="" href="#plugins_deprecated_assignmapper">assignmapper</a></li>

        
        <li><a style="" href="#plugins_deprecated_activemapper">ActiveMapper</a></li>

    </ul>

	        </li>
    </ul>

	        </li>
        
        <li><a style="" href="docstrings.html">API Documentation</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine">module sqlalchemy.engine</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.engine_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.engine_modfunc_create_engine">create_engine()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.engine_modfunc_engine_descriptors">engine_descriptors()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.engine_modfunc_engine_from_config">engine_from_config()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_BufferedColumnResultProxy">class BufferedColumnResultProxy(ResultProxy)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_BufferedColumnRow">class BufferedColumnRow(RowProxy)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_BufferedRowResultProxy">class BufferedRowResultProxy(ResultProxy)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Compiled">class Compiled(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Connectable">class Connectable(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Connection">class Connection(Connectable)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_DefaultRunner">class DefaultRunner(SchemaVisitor)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Dialect">class Dialect(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Engine">class Engine(Connectable)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_ExecutionContext">class ExecutionContext(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_NestedTransaction">class NestedTransaction(Transaction)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_ResultProxy">class ResultProxy(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_RootTransaction">class RootTransaction(Transaction)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_RowProxy">class RowProxy(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_SchemaIterator">class SchemaIterator(SchemaVisitor)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Transaction">class Transaction(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_TwoPhaseTransaction">class TwoPhaseTransaction(Transaction)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_engine_default.html#docstrings_sqlalchemy.engine.default">module sqlalchemy.engine.default</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_engine_default.html#docstrings_sqlalchemy.engine.default_DefaultDialect">class DefaultDialect(Dialect)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_default.html#docstrings_sqlalchemy.engine.default_DefaultExecutionContext">class DefaultExecutionContext(ExecutionContext)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_engine_strategies.html#docstrings_sqlalchemy.engine.strategies">module sqlalchemy.engine.strategies</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_engine_strategies.html#docstrings_sqlalchemy.engine.strategies_DefaultEngineStrategy">class DefaultEngineStrategy(EngineStrategy)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_strategies.html#docstrings_sqlalchemy.engine.strategies_EngineStrategy">class EngineStrategy(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_strategies.html#docstrings_sqlalchemy.engine.strategies_MockEngineStrategy">class MockEngineStrategy(EngineStrategy)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_strategies.html#docstrings_sqlalchemy.engine.strategies_PlainEngineStrategy">class PlainEngineStrategy(DefaultEngineStrategy)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_strategies.html#docstrings_sqlalchemy.engine.strategies_ThreadLocalEngineStrategy">class ThreadLocalEngineStrategy(DefaultEngineStrategy)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_engine_threadlocal.html#docstrings_sqlalchemy.engine.threadlocal">module sqlalchemy.engine.threadlocal</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_engine_threadlocal.html#docstrings_sqlalchemy.engine.threadlocal_TLConnection">class TLConnection(Connection)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_threadlocal.html#docstrings_sqlalchemy.engine.threadlocal_TLEngine">class TLEngine(Engine)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_threadlocal.html#docstrings_sqlalchemy.engine.threadlocal_TLSession">class TLSession(object)</a></li>

        
        <li><a style="" href="sqlalchemy_engine_threadlocal.html#docstrings_sqlalchemy.engine.threadlocal_TLTransaction">class TLTransaction(Transaction)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_engine_url.html#docstrings_sqlalchemy.engine.url">module sqlalchemy.engine.url</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.engine.url_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.engine.url_modfunc_make_url">make_url()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_engine_url.html#docstrings_sqlalchemy.engine.url_URL">class URL(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions">module sqlalchemy.exceptions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_ArgumentError">class ArgumentError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_AssertionError">class AssertionError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_CircularDependencyError">class CircularDependencyError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_CompileError">class CompileError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_ConcurrentModificationError">class ConcurrentModificationError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_DBAPIError">class DBAPIError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_DataError">class DataError(DatabaseError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_DatabaseError">class DatabaseError(DBAPIError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_DisconnectionError">class DisconnectionError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_FlushError">class FlushError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_IdentifierError">class IdentifierError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_IntegrityError">class IntegrityError(DatabaseError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_InterfaceError">class InterfaceError(DBAPIError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_InternalError">class InternalError(DatabaseError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_InvalidRequestError">class InvalidRequestError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_NoReferencedTableError">class NoReferencedTableError(InvalidRequestError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_NoSuchColumnError">class NoSuchColumnError(KeyError,SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_NoSuchTableError">class NoSuchTableError(InvalidRequestError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_NotSupportedError">class NotSupportedError(DatabaseError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_OperationalError">class OperationalError(DatabaseError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_ProgrammingError">class ProgrammingError(DatabaseError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_SADeprecationWarning">class SADeprecationWarning(DeprecationWarning)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_SAPendingDeprecationWarning">class SAPendingDeprecationWarning(PendingDeprecationWarning)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_SAWarning">class SAWarning(RuntimeWarning)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_SQLAlchemyError">class SQLAlchemyError(Exception)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_TimeoutError">class TimeoutError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_UnboundExecutionError">class UnboundExecutionError(InvalidRequestError)</a></li>

        
        <li><a style="" href="sqlalchemy_exceptions.html#docstrings_sqlalchemy.exceptions_UnmappedColumnError">class UnmappedColumnError(InvalidRequestError)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_interfaces.html#docstrings_sqlalchemy.interfaces">module sqlalchemy.interfaces</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_interfaces.html#docstrings_sqlalchemy.interfaces_PoolListener">class PoolListener(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool">module sqlalchemy.pool</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.pool_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.pool_modfunc_as_interface">as_interface()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.pool_modfunc_clear_managers">clear_managers()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.pool_modfunc_manage">manage()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool_AssertionPool">class AssertionPool(Pool)</a></li>

        
        <li><a style="" href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool_NullPool">class NullPool(Pool)</a></li>

        
        <li><a style="" href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool_Pool">class Pool(object)</a></li>

        
        <li><a style="" href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool_QueuePool">class QueuePool(Pool)</a></li>

        
        <li><a style="" href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool_SingletonThreadPool">class SingletonThreadPool(Pool)</a></li>

        
        <li><a style="" href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool_StaticPool">class StaticPool(Pool)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema">module sqlalchemy.schema</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_CheckConstraint">class CheckConstraint(Constraint)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_Column">class Column(SchemaItem,_ColumnClause)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_ColumnDefault">class ColumnDefault(DefaultGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_Constraint">class Constraint(SchemaItem)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_DDL">class DDL(object)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_DefaultGenerator">class DefaultGenerator(SchemaItem)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_ForeignKey">class ForeignKey(SchemaItem)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_ForeignKeyConstraint">class ForeignKeyConstraint(Constraint)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_Index">class Index(SchemaItem)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_MetaData">class MetaData(SchemaItem)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_PassiveDefault">class PassiveDefault(DefaultGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_PrimaryKeyConstraint">class PrimaryKeyConstraint(Constraint)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_SchemaItem">class SchemaItem(object)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_SchemaVisitor">class SchemaVisitor(ClauseVisitor)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_Sequence">class Sequence(DefaultGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_Table">class Table(SchemaItem,TableClause)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_ThreadLocalMetaData">class ThreadLocalMetaData(MetaData)</a></li>

        
        <li><a style="" href="sqlalchemy_schema.html#docstrings_sqlalchemy.schema_UniqueConstraint">class UniqueConstraint(Constraint)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_sql_compiler.html#docstrings_sqlalchemy.sql.compiler">module sqlalchemy.sql.compiler</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_sql_compiler.html#docstrings_sqlalchemy.sql.compiler_DDLBase">class DDLBase(SchemaIterator)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_compiler.html#docstrings_sqlalchemy.sql.compiler_DefaultCompiler">class DefaultCompiler(Compiled)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_compiler.html#docstrings_sqlalchemy.sql.compiler_IdentifierPreparer">class IdentifierPreparer(object)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_compiler.html#docstrings_sqlalchemy.sql.compiler_SchemaDropper">class SchemaDropper(DDLBase)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_compiler.html#docstrings_sqlalchemy.sql.compiler_SchemaGenerator">class SchemaGenerator(DDLBase)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression">module sqlalchemy.sql.expression</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_alias">alias()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_and_">and_()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_asc">asc()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_between">between()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_bindparam">bindparam()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_case">case()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_cast">cast()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_collate">collate()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_column">column()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_delete">delete()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_desc">desc()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_distinct">distinct()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_except_">except_()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_except_all">except_all()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_exists">exists()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_extract">extract()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_insert">insert()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_intersect">intersect()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_intersect_all">intersect_all()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_is_column">is_column()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_join">join()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_label">label()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_literal">literal()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_literal_column">literal_column()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_not_">not_()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_null">null()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_or_">or_()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_outerjoin">outerjoin()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_outparam">outparam()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_select">select()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_subquery">subquery()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_table">table()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_text">text()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_union">union()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_union_all">union_all()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.sql.expression_modfunc_update">update()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Alias">class Alias(FromClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__BinaryExpression">class _BinaryExpression(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__BindParamClause">class _BindParamClause(ClauseElement,_CompareMixin)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__CalculatedClause">class _CalculatedClause(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__Cast">class _Cast(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_ClauseElement">class ClauseElement(object)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_ClauseList">class ClauseList(ClauseElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__ColumnClause">class _ColumnClause(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_ColumnCollection">class ColumnCollection(OrderedProperties)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_ColumnElement">class ColumnElement(ClauseElement,_CompareMixin)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__ColumnElementAdapter">class _ColumnElementAdapter(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_ColumnOperators">class ColumnOperators(Operators)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_ColumnSet">class ColumnSet(OrderedSet)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__CompareMixin">class _CompareMixin(ColumnOperators)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_CompoundSelect">class CompoundSelect(_SelectBaseMixin,FromClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Delete">class Delete(_UpdateBase)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__Exists">class _Exists(_UnaryExpression)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__FigureVisitName">class _FigureVisitName(type)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_FromClause">class FromClause(Selectable)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__FromGrouping">class _FromGrouping(FromClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__Function">class _Function(_CalculatedClause,FromClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__FunctionGenerator">class _FunctionGenerator(object)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__Grouping">class _Grouping(_ColumnElementAdapter)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__IdentifiedClause">class _IdentifiedClause(ClauseElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Insert">class Insert(_ValuesBase)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Join">class Join(FromClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__Label">class _Label(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__Null">class _Null(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Operators">class Operators(object)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_ReleaseSavepointClause">class ReleaseSavepointClause(_IdentifiedClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_RollbackToSavepointClause">class RollbackToSavepointClause(_IdentifiedClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_SavepointClause">class SavepointClause(_IdentifiedClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__ScalarSelect">class _ScalarSelect(_Grouping)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Select">class Select(_SelectBaseMixin,FromClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__SelectBaseMixin">class _SelectBaseMixin(object)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Selectable">class Selectable(ClauseElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_TableClause">class TableClause(FromClause)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__TextClause">class _TextClause(ClauseElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__TypeClause">class _TypeClause(ClauseElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__UnaryExpression">class _UnaryExpression(ColumnElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression_Update">class Update(_ValuesBase)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__UpdateBase">class _UpdateBase(ClauseElement)</a></li>

        
        <li><a style="" href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression__ValuesBase">class _ValuesBase(_UpdateBase)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types">module sqlalchemy.types</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_AbstractType">class AbstractType(object)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_BLOB">class BLOB(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_BOOLEAN">class BOOLEAN(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Binary">class Binary(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Boolean">class Boolean(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_CHAR">class CHAR(String)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_CLOB">class CLOB(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_DATE">class DATE(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_DATETIME">class DATETIME(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_DECIMAL">class DECIMAL(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Date">class Date(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_DateTime">class DateTime(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_FLOAT">class FLOAT(Float)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Float">class Float(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_INT">class INT(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Integer">class Integer(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Interval">class Interval(TypeDecorator)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_NCHAR">class NCHAR(Unicode)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_NUMERIC">class NUMERIC(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Numeric">class Numeric(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_PickleType">class PickleType(MutableType,TypeDecorator)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_SMALLINT">class SMALLINT(SmallInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_SmallInteger">class SmallInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_String">class String(Concatenable,TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_TIME">class TIME(Time)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_TIMESTAMP">class TIMESTAMP(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Text">class Text(String)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Time">class Time(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_TypeDecorator">class TypeDecorator(AbstractType)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_TypeEngine">class TypeEngine(AbstractType)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_Unicode">class Unicode(String)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_UnicodeText">class UnicodeText(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_types.html#docstrings_sqlalchemy.types_VARCHAR">class VARCHAR(String)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm">module sqlalchemy.orm</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_backref">backref()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_class_mapper">class_mapper()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_clear_mappers">clear_mappers()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_column_property">column_property()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_comparable_property">comparable_property()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_compile_mappers">compile_mappers()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_composite">composite()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_contains_alias">contains_alias()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_contains_eager">contains_eager()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_create_session">create_session()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_defer">defer()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_deferred">deferred()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_dynamic_loader">dynamic_loader()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_eagerload">eagerload()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_eagerload_all">eagerload_all()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_extension">extension()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_lazyload">lazyload()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_mapper">mapper()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_noload">noload()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_object_mapper">object_mapper()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_object_session">object_session()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_polymorphic_union">polymorphic_union()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_relation">relation()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_scoped_session">scoped_session()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_sessionmaker">sessionmaker()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_synonym">synonym()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_undefer">undefer()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm_modfunc_undefer_group">undefer_group()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm_AliasedClass">class AliasedClass(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm_MapperExtension">class MapperExtension(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm_PropComparator">class PropComparator(ColumnOperators)</a></li>

        
        <li><a style="" href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm_Query">class Query(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_collections.html#docstrings_sqlalchemy.orm.collections">module sqlalchemy.orm.collections</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm.collections_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm.collections_modfunc_attribute_mapped_collection">attribute_mapped_collection()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm.collections_modfunc_collection_adapter">collection_adapter()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm.collections_modfunc_column_mapped_collection">column_mapped_collection()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm.collections_modfunc_mapped_collection">mapped_collection()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_collections.html#docstrings_sqlalchemy.orm.collections_collection">class collection(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_collections.html#docstrings_sqlalchemy.orm.collections_MappedCollection">class MappedCollection(dict)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_collections.html#docstrings_sqlalchemy.orm.collections_CollectionAdapter">class CollectionAdapter(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces">module sqlalchemy.orm.interfaces</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm.interfaces_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm.interfaces_modfunc_build_path">build_path()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_AttributeExtension">class AttributeExtension(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_ExtensionOption">class ExtensionOption(MapperOption)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_LoaderStrategy">class LoaderStrategy(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_MapperExtension">class MapperExtension(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_MapperOption">class MapperOption(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_MapperProperty">class MapperProperty(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_PropComparator">class PropComparator(ColumnOperators)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_PropertyOption">class PropertyOption(MapperOption)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_StrategizedOption">class StrategizedOption(PropertyOption)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_interfaces.html#docstrings_sqlalchemy.orm.interfaces_StrategizedProperty">class StrategizedProperty(MapperProperty)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_mapper.html#docstrings_sqlalchemy.orm.mapper">module sqlalchemy.orm.mapper</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm.mapper_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.orm.mapper_modfunc_class_mapper">class_mapper()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.orm.mapper_modfunc_object_mapper">object_mapper()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_mapper.html#docstrings_sqlalchemy.orm.mapper_Mapper">class Mapper(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_properties.html#docstrings_sqlalchemy.orm.properties">module sqlalchemy.orm.properties</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_orm_properties.html#docstrings_sqlalchemy.orm.properties_BackRef">class BackRef(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_properties.html#docstrings_sqlalchemy.orm.properties_ColumnProperty">class ColumnProperty(StrategizedProperty)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_properties.html#docstrings_sqlalchemy.orm.properties_ComparableProperty">class ComparableProperty(MapperProperty)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_properties.html#docstrings_sqlalchemy.orm.properties_CompositeProperty">class CompositeProperty(ColumnProperty)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_properties.html#docstrings_sqlalchemy.orm.properties_PropertyLoader">class PropertyLoader(StrategizedProperty)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_properties.html#docstrings_sqlalchemy.orm.properties_SynonymProperty">class SynonymProperty(MapperProperty)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_query.html#docstrings_sqlalchemy.orm.query">module sqlalchemy.orm.query</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_orm_query.html#docstrings_sqlalchemy.orm.query_Query">class Query(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_session.html#docstrings_sqlalchemy.orm.session">module sqlalchemy.orm.session</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_orm_session.html#docstrings_sqlalchemy.orm.session_Session">class Session(object)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_session.html#docstrings_sqlalchemy.orm.session_SessionExtension">class SessionExtension(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_orm_shard.html#docstrings_sqlalchemy.orm.shard">module sqlalchemy.orm.shard</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_orm_shard.html#docstrings_sqlalchemy.orm.shard_ShardedQuery">class ShardedQuery(Query)</a></li>

        
        <li><a style="" href="sqlalchemy_orm_shard.html#docstrings_sqlalchemy.orm.shard_ShardedSession">class ShardedSession(Session)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_ext_declarative.html#docstrings_sqlalchemy.ext.declarative">module sqlalchemy.ext.declarative</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.ext.declarative_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.ext.declarative_modfunc_comparable_using">comparable_using()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.ext.declarative_modfunc_declarative_base">declarative_base()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.ext.declarative_modfunc_declared_synonym">declared_synonym()</a></li>

        
        <li><a style="" href="#docstrings_sqlalchemy.ext.declarative_modfunc_synonym_for">synonym_for()</a></li>

    </ul>

	        </li>
    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_ext_associationproxy.html#docstrings_sqlalchemy.ext.associationproxy">module sqlalchemy.ext.associationproxy</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.ext.associationproxy_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.ext.associationproxy_modfunc_association_proxy">association_proxy()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_ext_associationproxy.html#docstrings_sqlalchemy.ext.associationproxy_AssociationProxy">class AssociationProxy(object)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_ext_orderinglist.html#docstrings_sqlalchemy.ext.orderinglist">module sqlalchemy.ext.orderinglist</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.ext.orderinglist_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.ext.orderinglist_modfunc_ordering_list">ordering_list()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_ext_orderinglist.html#docstrings_sqlalchemy.ext.orderinglist_OrderingList">class OrderingList(list)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_ext_sqlsoup.html#docstrings_sqlalchemy.ext.sqlsoup">module sqlalchemy.ext.sqlsoup</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_ext_sqlsoup.html#docstrings_sqlalchemy.ext.sqlsoup_PKNotFoundError">class PKNotFoundError(SQLAlchemyError)</a></li>

        
        <li><a style="" href="sqlalchemy_ext_sqlsoup.html#docstrings_sqlalchemy.ext.sqlsoup_SqlSoup">class SqlSoup()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite">module sqlalchemy.databases.sqlite</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.sqlite_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.sqlite_modfunc_descriptor">descriptor()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_DateTimeMixin">class DateTimeMixin(object)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_PassiveDefault">class PassiveDefault(DefaultGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLBinary">class SLBinary(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLBoolean">class SLBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLChar">class SLChar(SLUnicodeMixin,CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLDate">class SLDate(DateTimeMixin,Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLDateTime">class SLDateTime(DateTimeMixin,DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLFloat">class SLFloat(Float)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLInteger">class SLInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLNumeric">class SLNumeric(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLSmallInteger">class SLSmallInteger(SmallInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLString">class SLString(SLUnicodeMixin,String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLText">class SLText(SLUnicodeMixin,Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLTime">class SLTime(DateTimeMixin,Time)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SLUnicodeMixin">class SLUnicodeMixin(object)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SQLiteCompiler">class SQLiteCompiler(DefaultCompiler)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SQLiteDialect">class SQLiteDialect(DefaultDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SQLiteExecutionContext">class SQLiteExecutionContext(DefaultExecutionContext)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SQLiteIdentifierPreparer">class SQLiteIdentifierPreparer(IdentifierPreparer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SQLiteSchemaDropper">class SQLiteSchemaDropper(SchemaDropper)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sqlite.html#docstrings_sqlalchemy.databases.sqlite_SQLiteSchemaGenerator">class SQLiteSchemaGenerator(SchemaGenerator)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres">module sqlalchemy.databases.postgres</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.postgres_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.postgres_modfunc_descriptor">descriptor()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGArray">class PGArray(MutableType,Concatenable,TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGBigInteger">class PGBigInteger(PGInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGBinary">class PGBinary(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGBoolean">class PGBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGChar">class PGChar(CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGCidr">class PGCidr(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGCompiler">class PGCompiler(DefaultCompiler)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGDate">class PGDate(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGDateTime">class PGDateTime(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGDefaultRunner">class PGDefaultRunner(DefaultRunner)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGDialect">class PGDialect(DefaultDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGExecutionContext">class PGExecutionContext(DefaultExecutionContext)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGFloat">class PGFloat(Float)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGIdentifierPreparer">class PGIdentifierPreparer(IdentifierPreparer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGInet">class PGInet(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGInteger">class PGInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGInterval">class PGInterval(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGMacAddr">class PGMacAddr(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGNumeric">class PGNumeric(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGSchemaDropper">class PGSchemaDropper(SchemaDropper)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGSchemaGenerator">class PGSchemaGenerator(SchemaGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGSmallInteger">class PGSmallInteger(SmallInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGString">class PGString(String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGText">class PGText(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_postgres.html#docstrings_sqlalchemy.databases.postgres_PGTime">class PGTime(Time)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql">module sqlalchemy.databases.mysql</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSBigInteger">class MSBigInteger(MSInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSBinary">class MSBinary(_BinaryType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSBit">class MSBit(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSBlob">class MSBlob(_BinaryType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSBoolean">class MSBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSChar">class MSChar(_StringType,CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSDate">class MSDate(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSDateTime">class MSDateTime(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSDecimal">class MSDecimal(MSNumeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSDouble">class MSDouble(Float,_NumericType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSEnum">class MSEnum(MSString)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSFloat">class MSFloat(Float,_NumericType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSInteger">class MSInteger(Integer,_NumericType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSLongBlob">class MSLongBlob(MSBlob)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSLongText">class MSLongText(MSText)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSMediumBlob">class MSMediumBlob(MSBlob)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSMediumInteger">class MSMediumInteger(MSInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSMediumText">class MSMediumText(MSText)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSNChar">class MSNChar(_StringType,CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSNVarChar">class MSNVarChar(_StringType,String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSNumeric">class MSNumeric(Numeric,_NumericType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSSet">class MSSet(MSString)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSSmallInteger">class MSSmallInteger(SmallInteger,MSInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSString">class MSString(_StringType,String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSText">class MSText(_StringType,Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSTime">class MSTime(Time)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSTimeStamp">class MSTimeStamp(TIMESTAMP)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSTinyBlob">class MSTinyBlob(MSBlob)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSTinyInteger">class MSTinyInteger(MSInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSTinyText">class MSTinyText(MSText)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSVarBinary">class MSVarBinary(_BinaryType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mysql.html#docstrings_sqlalchemy.databases.mysql_MSYear">class MSYear(TypeEngine)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle">module sqlalchemy.databases.oracle</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.oracle_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.oracle_modfunc_descriptor">descriptor()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleBinary">class OracleBinary(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleBoolean">class OracleBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleChar">class OracleChar(CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleCompiler">class OracleCompiler(DefaultCompiler)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleDate">class OracleDate(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleDateTime">class OracleDateTime(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleDefaultRunner">class OracleDefaultRunner(DefaultRunner)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleDialect">class OracleDialect(DefaultDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleExecutionContext">class OracleExecutionContext(DefaultExecutionContext)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleIdentifierPreparer">class OracleIdentifierPreparer(IdentifierPreparer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleInteger">class OracleInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleNumeric">class OracleNumeric(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleRaw">class OracleRaw(OracleBinary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleSchemaDropper">class OracleSchemaDropper(SchemaDropper)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleSchemaGenerator">class OracleSchemaGenerator(SchemaGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleSmallInteger">class OracleSmallInteger(SmallInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleString">class OracleString(String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleText">class OracleText(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_oracle.html#docstrings_sqlalchemy.databases.oracle_OracleTimestamp">class OracleTimestamp(TIMESTAMP)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql">module sqlalchemy.databases.mssql</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.mssql_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.mssql_modfunc_descriptor">descriptor()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_AdoMSNVarchar">class AdoMSNVarchar(MSNVarchar)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_Decimal">class Decimal(object)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSBigInteger">class MSBigInteger(MSInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSBinary">class MSBinary(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSBoolean">class MSBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSChar">class MSChar(CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSDate">class MSDate(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSDateTime">class MSDateTime(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSDateTime_adodbapi">class MSDateTime_adodbapi(MSDateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSDateTime_pyodbc">class MSDateTime_pyodbc(MSDateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSDate_pyodbc">class MSDate_pyodbc(MSDate)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSFloat">class MSFloat(Float)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSInteger">class MSInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSMoney">class MSMoney(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSNChar">class MSNChar(NCHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSNVarchar">class MSNVarchar(Unicode)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSNumeric">class MSNumeric(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLCompiler">class MSSQLCompiler(DefaultCompiler)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLDefaultRunner">class MSSQLDefaultRunner(DefaultRunner)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLDialect">class MSSQLDialect(DefaultDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLDialect_adodbapi">class MSSQLDialect_adodbapi(MSSQLDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLDialect_pymssql">class MSSQLDialect_pymssql(MSSQLDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLDialect_pyodbc">class MSSQLDialect_pyodbc(MSSQLDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLExecutionContext">class MSSQLExecutionContext(DefaultExecutionContext)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLExecutionContext_pyodbc">class MSSQLExecutionContext_pyodbc(MSSQLExecutionContext)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLIdentifierPreparer">class MSSQLIdentifierPreparer(IdentifierPreparer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLSchemaDropper">class MSSQLSchemaDropper(SchemaDropper)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSQLSchemaGenerator">class MSSQLSchemaGenerator(SchemaGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSmallDate">class MSSmallDate(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSmallInteger">class MSSmallInteger(MSInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSSmallMoney">class MSSmallMoney(MSMoney)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSString">class MSString(String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSText">class MSText(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSTime">class MSTime(Time)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSTimeStamp">class MSTimeStamp(TIMESTAMP)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSTinyInteger">class MSTinyInteger(MSInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSUniqueIdentifier">class MSUniqueIdentifier(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_mssql.html#docstrings_sqlalchemy.databases.mssql_MSVariant">class MSVariant(TypeEngine)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird">module sqlalchemy.databases.firebird</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.firebird_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.firebird_modfunc_descriptor">descriptor()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBBinary">class FBBinary(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBBoolean">class FBBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBChar">class FBChar(CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBCompiler">class FBCompiler(DefaultCompiler)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBDate">class FBDate(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBDateTime">class FBDateTime(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBDefaultRunner">class FBDefaultRunner(DefaultRunner)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBDialect">class FBDialect(DefaultDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBExecutionContext">class FBExecutionContext(DefaultExecutionContext)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBFloat">class FBFloat(Float)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBIdentifierPreparer">class FBIdentifierPreparer(IdentifierPreparer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBInteger">class FBInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBNumeric">class FBNumeric(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBSchemaDropper">class FBSchemaDropper(SchemaDropper)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBSchemaGenerator">class FBSchemaGenerator(SchemaGenerator)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBSmallInteger">class FBSmallInteger(SmallInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBString">class FBString(String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBText">class FBText(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_firebird.html#docstrings_sqlalchemy.databases.firebird_FBTime">class FBTime(Time)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase">module sqlalchemy.databases.sybase</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseBigInteger">class SybaseBigInteger(SybaseInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseBinary">class SybaseBinary(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseBoolean">class SybaseBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseChar">class SybaseChar(CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseDateTime_mxodbc">class SybaseDateTime_mxodbc(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseDateTime_pyodbc">class SybaseDateTime_pyodbc(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseDate_mxodbc">class SybaseDate_mxodbc(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseDate_pyodbc">class SybaseDate_pyodbc(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseFloat">class SybaseFloat(FLOAT,SybaseNumeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseInteger">class SybaseInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseMoney">class SybaseMoney(TypeEngine)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseSmallInteger">class SybaseSmallInteger(SybaseInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseSmallMoney">class SybaseSmallMoney(SybaseMoney)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseString">class SybaseString(String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseText">class SybaseText(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseTimeStamp">class SybaseTimeStamp(TIMESTAMP)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseTime_mxodbc">class SybaseTime_mxodbc(Time)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseTime_pyodbc">class SybaseTime_pyodbc(Time)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseTinyInteger">class SybaseTinyInteger(SybaseInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_sybase.html#docstrings_sqlalchemy.databases.sybase_SybaseUniqueIdentifier">class SybaseUniqueIdentifier(TypeEngine)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access">module sqlalchemy.databases.access</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.access_modfunc">Module Functions</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="#docstrings_sqlalchemy.databases.access_modfunc_descriptor">descriptor()</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcBinary">class AcBinary(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcBoolean">class AcBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcChar">class AcChar(CHAR)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcDate">class AcDate(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcDateTime">class AcDateTime(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcFloat">class AcFloat(Float)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcInteger">class AcInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcNumeric">class AcNumeric(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcSmallInteger">class AcSmallInteger(SmallInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcString">class AcString(String)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcText">class AcText(Text)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcTimeStamp">class AcTimeStamp(TIMESTAMP)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcTinyInteger">class AcTinyInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AcUnicode">class AcUnicode(Unicode)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AccessCompiler">class AccessCompiler(DefaultCompiler)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AccessDefaultRunner">class AccessDefaultRunner(DefaultRunner)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AccessDialect">class AccessDialect(DefaultDialect)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AccessExecutionContext">class AccessExecutionContext(DefaultExecutionContext)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AccessIdentifierPreparer">class AccessIdentifierPreparer(IdentifierPreparer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AccessSchemaDropper">class AccessSchemaDropper(SchemaDropper)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_access.html#docstrings_sqlalchemy.databases.access_AccessSchemaGenerator">class AccessSchemaGenerator(SchemaGenerator)</a></li>

    </ul>

	        </li>
        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb">module sqlalchemy.databases.maxdb</a></li>

	        <li>
                
    <ul>
        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxBlob">class MaxBlob(Binary)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxBoolean">class MaxBoolean(Boolean)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxChar">class MaxChar(_StringType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxDate">class MaxDate(Date)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxFloat">class MaxFloat(Float)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxInteger">class MaxInteger(Integer)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxNumeric">class MaxNumeric(Numeric)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxSmallInteger">class MaxSmallInteger(MaxInteger)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxString">class MaxString(_StringType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxText">class MaxText(_StringType)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxTime">class MaxTime(Time)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxTimestamp">class MaxTimestamp(DateTime)</a></li>

        
        <li><a style="" href="sqlalchemy_databases_maxdb.html#docstrings_sqlalchemy.databases.maxdb_MaxUnicode">class MaxUnicode(_StringType)</a></li>

    </ul>

	        </li>
    </ul>

	        </li>
        
        <li><a style="" href="#copyright">Appendix:  Copyright</a></li>

    </ul>


	</div>




    
    
    <A name="overview"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">


            
            Next: <a href="#datamapping">Object Relational Tutorial</a>
    </div>

        <h2>Overview / Installation</h2>
    </div>


        








    
    <A name="overview"></a>
    
    <div class="sectionL1">

    
    



    
    <A name="overview_overview"></a>
    
    <div class="sectionL2">

    <h3>Overview</h3>
    
    

<p>The SQLAlchemy SQL Toolkit and Object Relational Mapper is a comprehensive set of tools for working with databases and Python.  It has several distinct areas of functionality which can be used individually or combined together.  Its major API components, all public-facing, are illustrated below:
</p>

    

    <div class="sliding_code">
        <pre>
           +-----------------------------------------------------------+
           |             Object Relational Mapper (ORM)                |
           |                <a href="#datamapping">[tutorial]</a>    <a href="#advdatamapping">[docs]</a>                       |
           +-----------------------------------------------------------+
           +---------+ +------------------------------------+ +--------+
           |         | |       SQL Expression Language      | |        |
           |         | |        <a href="#sql">[tutorial]</a>  <a href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression">[docs]</a>          | |        |
           |         | +------------------------------------+ |        |
           |         +-----------------------+ +--------------+        |
           |        Dialect/Execution        | |    Schema Management  |
           |              <a href="#dbengine">[docs]</a>             | |        <a href="#metadata">[docs]</a>         |
           +---------------------------------+ +-----------------------+
           +----------------------+ +----------------------------------+
           |  Connection Pooling  | |              Types               |
           |        <a href="#pooling">[docs]</a>        | |              <a href="#types">[docs]</a>              |
           +----------------------+ +----------------------------------+
</pre>
    </div>
<p>Above, the two most significant front-facing portions of SQLAlchemy are the <strong>Object Relational Mapper</strong> and the <strong>SQL Expression Language</strong>.  These are two separate toolkits, one building off the other.  SQL Expressions can be used independently of the ORM.  When using the ORM, the SQL Expression language is used to establish object-relational configurations as well as in querying.
</p>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_tutorials"></a>
    
    <div class="sectionL2">

    <h3>Tutorials</h3>
    
    

<ul>
 <li>
     <a href="#datamapping">Object Relational Tutorial</a> - This describes the richest feature of SQLAlchemy, its object relational mapper.  If you want to work with higher-level SQL which is constructed automatically for you, as well as management of Python objects, proceed to this tutorial.
 </li>

 <li>
     <a href="#sql">SQL Expression Tutorial</a> - The core of SQLAlchemy is its SQL expression language.  The SQL Expression Language is a toolkit all its own, independent of the ORM package, which can be used to construct manipulable SQL expressions which can be programmatically constructed, modified, and executed, returning cursor-like result sets.  It's a lot more lightweight than the ORM and is appropriate for higher scaling SQL operations.  It's also heavily present within the ORM's public facing API, so advanced ORM users will want to master this language as well.
 </li>
</ul>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_reference"></a>
    
    <div class="sectionL2">

    <h3>Reference Documentation</h3>
    
    

<ul>
 <li>
     <a href="#advdatamapping">Datamapping</a> - A comprehensive walkthrough of major ORM patterns and techniques.
 </li>

 <li>
     <a href="#unitofwork">Session</a> - A detailed description of SQLAlchemy's Session object
 </li>

 <li>
     <a href="#dbengine">Engines</a> - Describes SQLAlchemy's database-connection facilities, including connection documentation and working with connections and transactions. 
 </li>

 <li>
     <a href="#pooling">Connection Pools</a> - Further detail about SQLAlchemy's connection pool library.
 </li>

 <li>
     <a href="#metadata">Metadata</a> - All about schema management using <code>MetaData</code> and <code>Table</code> objects; reading database schemas into your application, creating and dropping tables, constraints, defaults, sequences, indexes.
 </li>

 <li>
     <a href="#types">Types</a> - Datatypes included with SQLAlchemy, their functions, as well as how to create your own types.
 </li>

 <li>
     <a href="#plugins">Plugins</a> - Included addons for SQLAlchemy
 </li>
</ul>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_sqlalchemy"></a>
    
    <div class="sectionL2">

    <h3>Installing SQLAlchemy</h3>
    
    

<p>Installing SQLAlchemy from scratch is most easily achieved with <a href='http://peak.telecommunity.com/DevCenter/setuptools'>setuptools</a>.  (<a href='http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions'>setuptools installation</a>). Just run this from the command-line:
</p>
<pre><code># easy_install SQLAlchemy
</code></pre><p>This command will download the latest version of SQLAlchemy from the <a href='http://pypi.python.org/pypi/SQLAlchemy'>Python Cheese Shop</a> and install it to your system.
</p>
<p>Otherwise, you can install from the distribution using the <code>setup.py</code> script:
</p>
<pre><code># python setup.py install
</code></pre>

    
    <A name="overview_sqlalchemy_dbms"></a>
    
    <div class="sectionL3">

    <h3>Installing a Database API</h3>
    
    

<p>SQLAlchemy is designed to operate with a <a href='http://www.python.org/doc/peps/pep-0249/'>DB-API</a> implementation built for a particular database, and includes support for the most popular databases:
</p>
<ul>
 <li>
     Postgres:  <a href='http://www.initd.org/tracker/psycopg/wiki/PsycopgTwo'>psycopg2</a>
 </li>

 <li>
     SQLite:  <a href='http://initd.org/tracker/pysqlite'>pysqlite</a>, <a href='http://docs.python.org/lib/module-sqlite3.html'>sqlite3</a> (included with Python 2.5 or greater)
 </li>

 <li>
     MySQL:   <a href='http://sourceforge.net/projects/mysql-python'>MySQLdb</a>
 </li>

 <li>
     Oracle:  <a href='http://www.cxtools.net/default.aspx?nav=home'>cx_Oracle</a>
 </li>

 <li>
     MS-SQL:  <a href='http://pyodbc.sourceforge.net/'>pyodbc</a> (recommended), <a href='http://adodbapi.sourceforge.net/'>adodbapi</a>  or <a href='http://pymssql.sourceforge.net/'>pymssql</a>
 </li>

 <li>
     Firebird:  <a href='http://kinterbasdb.sourceforge.net/'>kinterbasdb</a>
 </li>

 <li>
     Informix:  <a href='http://informixdb.sourceforge.net/'>informixdb</a>
 </li>
</ul>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_sqlalchemy_checking"></a>
    
    <div class="sectionL3">

    <h3>Checking the Installed SQLAlchemy Version</h3>
    
    

<p>This documentation covers SQLAlchemy version 0.4.  If you're working on a system that already has SQLAlchemy installed, check the version from your Python prompt like this:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">__version__ </span><span class="python_operator">
</span><span class="python_number">0.4.0</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#overview" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="overview_migration"></a>
    
    <div class="sectionL2">

    <h3>0.3 to 0.4 Migration</h3>
    
    

<p>From version 0.3 to version 0.4 of SQLAlchemy, some conventions have changed.  Most of these conventions are available in the most recent releases of the 0.3 series starting with version 0.3.9, so that you can make a 0.3 application compatible with 0.4 in most cases.
</p>
<p>This section will detail only those things that have changed in a backwards-incompatible manner.  For a full overview of everything that's new and changed, see <a href='http://www.sqlalchemy.org/trac/wiki/WhatsNewIn04'>WhatsNewIn04</a>.
</p>


    
    <A name="overview_migration_imports"></a>
    
    <div class="sectionL3">

    <h3>ORM Package is now sqlalchemy.orm</h3>
    
    

<p>All symbols related to the SQLAlchemy Object Relational Mapper, i.e. names like <code>mapper()</code>, <code>relation()</code>, <code>backref()</code>, <code>create_session()</code> <code>synonym()</code>, <code>eagerload()</code>, etc. are now only in the <code>sqlalchemy.orm</code> package, and <strong>not</strong> in <code>sqlalchemy</code>.  So if you were previously importing everything on an asterisk:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_operator">*
</span></pre>
    </div>
<p>You should now import separately from orm:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_operator">*
</span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_operator">*
</span></pre>
    </div>
<p>Or more commonly, just pull in the names you'll need:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">create_engine</span><span class="python_operator">, </span><span class="python_name">MetaData</span><span class="python_operator">, </span><span class="python_name">Table</span><span class="python_operator">, </span><span class="python_name">Column</span><span class="python_operator">, </span><span class="python_name">types</span><span class="python_operator">
</span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">mapper</span><span class="python_operator">, </span><span class="python_name">relation</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">, </span><span class="python_name">create_session</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_migration_metadata"></a>
    
    <div class="sectionL3">

    <h3>BoundMetaData is now MetaData</h3>
    
    

<p>The <code>BoundMetaData</code> name is removed.  Now, you just use <code>MetaData</code>.  Additionally, the <code>engine</code> parameter/attribute is now called <code>bind</code>, and <code>connect()</code> is deprecated:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># plain metadata
</span><span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># metadata bound to an engine
</span><span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># bind metadata to an engine later
</span><span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">
</span></pre>
    </div>
<p>Additionally, <code>DynamicMetaData</code> is now known as <code>ThreadLocalMetaData</code>.
</p>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_migration_global"></a>
    
    <div class="sectionL3">

    <h3>"Magic" Global MetaData removed</h3>
    
    

<p>There was an old way to specify <code>Table</code> objects using an implicit, global <code>MetaData</code> object.  To do this you'd omit the second positional argument, and specify <code>Table('tablename', Column(...))</code>.  This no longer exists in 0.4 and the second <code>MetaData</code> positional argument is required, i.e. <code>Table('tablename', meta, Column(...))</code>.
</p>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_migration_generative"></a>
    
    <div class="sectionL3">

    <h3>Some existing select() methods become generative</h3>
    
    

<p>The methods <code>correlate()</code>, <code>order_by()</code>, and <code>group_by()</code> on the <code>select()</code> construct now return a <strong>new</strong> select object, and do not change the original one.  Additionally, the generative methods <code>where()</code>, <code>column()</code>, <code>distinct()</code>, and several others have been added:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">(</span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">where</span><span class="python_enclosure">(</span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">x</span><span class="python_operator">==</span><span class="python_number">7</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_migration_collection"></a>
    
    <div class="sectionL3">

    <h3>collection_class behavior is changed</h3>
    
    

<p>If you've been using the <code>collection_class</code> option on <code>mapper()</code>, the requirements for instrumented collections have changed.  For an overview, see <a href="#advdatamapping_relation_collections">Alternate Collection Implementations</a>.
</p>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_migration_bind"></a>
    
    <div class="sectionL3">

    <h3>All "engine", "bind_to", "connectable" Keyword Arguments Changed to "bind"</h3>
    
    

<p>This is for create/drop statements, sessions, SQL constructs, metadatas:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">myengine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite://'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">(</span><span class="python_name">myengine</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">meta2 </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">meta2</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">myengine</span><span class="python_operator">
</span>
<span class="python_name">session </span><span class="python_operator">= </span><span class="python_name">create_session</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">myengine</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">statement </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">table</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">myengine</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">myengine</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_migration_type"></a>
    
    <div class="sectionL3">

    <h3>All "type" Keyword Arguments Changed to "type_"</h3>
    
    

<p>This mostly applies to SQL constructs where you pass a type in:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">mytable</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">x</span><span class="python_operator">=</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_name">y</span><span class="python_operator">, </span><span class="python_name">type_</span><span class="python_operator">=</span><span class="python_name">DateTime</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">now</span><span class="python_enclosure">(</span><span class="python_name">type_</span><span class="python_operator">=</span><span class="python_name">DateTime</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#overview" class="totoc">back to section top</a>
    </div>



    
    <A name="overview_migration_mapper"></a>
    
    <div class="sectionL3">

    <h3>Mapper Extensions must return EXT_CONTINUE to continue execution to the next mapper</h3>
    
    

<p>If you extend the mapper, the methods in your mapper extension must return EXT_CONTINUE to continue executing additional mappers.
</p>




            <a href="#overview" class="totoc">back to section top</a>
    </div>




    </div>




    </div>



    
    
    <A name="datamapping"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#overview">Overview / Installation</a>

               |   
            Next: <a href="#sql">SQL Expression Language Tutorial</a>
    </div>

        <h2>Object Relational Tutorial</h2>
    </div>


        








    
    <A name="datamapping"></a>
    
    <div class="sectionL1">

    
    

<p>In this tutorial we will cover a basic SQLAlchemy object-relational mapping scenario, where we store and retrieve Python objects from a database representation.  The database schema will begin with one table, and will later develop into several.  The tutorial is in doctest format, meaning each <code>&gt;&gt;&gt;</code> line represents something you can type at a Python command prompt, and the following text represents the expected return value.  The tutorial has no prerequisites.
</p>


    
    <A name="datamapping_version"></a>
    
    <div class="sectionL2">

    <h3>Version Check</h3>
    
    

<p>A quick check to verify that we are on at least <strong>version 0.4</strong> of SQLAlchemy:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">__version__ </span><span class="python_operator">
</span><span class="python_number">0.4.0</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_connecting"></a>
    
    <div class="sectionL2">

    <h3>Connecting</h3>
    
    

<p>For this tutorial we will use an in-memory-only SQLite database.   This is an easy way to test things without needing to have an actual database defined anywhere.  To connect we use <code>create_engine()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">create_engine</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///:memory:'</span><span class="python_operator">, </span><span class="python_name">echo</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>echo</code> flag is a shortcut to setting up SQLAlchemy logging, which is accomplished via Python's standard <code>logging</code> module.  With it enabled, we'll see all the generated SQL produced.  If you are working through this tutorial and want less output generated, set it to <code>False</code>.   This tutorial will format the SQL behind a popup window so it doesn't get in our way; just click the "SQL" links to see whats being generated.
</p>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_tables"></a>
    
    <div class="sectionL2">

    <h3>Define and Create a Table</h3>
    
    

<p>Next we want to tell SQLAlchemy about our tables.  We will start with just a single table called <code>users</code>, which will store records for the end-users using our application (lets assume it's a website).  We define our tables all within a catalog called <code>MetaData</code>, using the <code>Table</code> construct, which resembles regular SQL CREATE TABLE syntax:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">Table</span><span class="python_operator">, </span><span class="python_name">Column</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_operator">, </span><span class="python_name">MetaData</span><span class="python_operator">, </span><span class="python_name">ForeignKey    </span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">metadata </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">users_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">40</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'fullname'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'password'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">15</span><span class="python_enclosure">))</span>
<span class="python_operator">... </span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>All about how to define <code>Table</code> objects, as well as how to create them from an existing database automatically, is described in <a href="#metadata">Database Meta Data</a>.
</p>
<p>Next, to tell the <code>MetaData</code> we'd actually like to create our <code>users_table</code> for real inside the SQLite database, we use <code>create_all()</code>, passing it the <code>engine</code> instance which points to our database.  This will check for the presence of a table first before creating, so it's safe to call multiple times:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_1', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator"> </span></pre><div id="popbox_1_div" class="codepop" style="display:none;">PRAGMA table_info(&quot;users&quot;)<br/>
{}<br/>
CREATE TABLE users (<br/>
    id INTEGER NOT NULL, <br/>
    name VARCHAR(40), <br/>
    fullname VARCHAR(100), <br/>
    password VARCHAR(15), <br/>
    PRIMARY KEY (id)<br/>
)<br/>
{}<br/>
COMMIT</div><pre><span class="python_operator"></span></pre>
    </div>
<p>So now our database is created, our initial schema is present, and our SQLAlchemy application knows all about the tables and columns in the database; this information is to be re-used by the Object Relational Mapper, as we'll see now.
</p>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_mapping"></a>
    
    <div class="sectionL2">

    <h3>Define a Python Class to be Mapped</h3>
    
    

<p>So lets create a rudimentary <code>User</code> object to be mapped in the database.  This object will for starters have three attributes, <code>name</code>, <code>fullname</code> and <code>password</code>.  It only need subclass Python's built-in <code>object</code> class (i.e. it's a new style class).  We will give it a constructor so that it may conveniently be instantiated with its attributes at once, as well as a <code>__repr__</code> method so that we can get a nice string representation of it:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">fullname</span><span class="python_operator">, </span><span class="python_name">password</span><span class="python_enclosure">)</span><span class="python_operator">:
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">= </span><span class="python_name">fullname</span><span class="python_operator">
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">password </span><span class="python_operator">= </span><span class="python_name">password</span><span class="python_operator">
...
...     </span><span class="python_keyword">def </span><span class="python_name">__repr__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
...        </span><span class="python_keyword">return </span><span class="python_literal">"&lt;User('%s','%s', '%s')&gt;" </span><span class="python_operator">% </span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_operator">, </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">password</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_setting"></a>
    
    <div class="sectionL2">

    <h3>Setting up the Mapping</h3>
    
    

<p>With our <code>users_table</code> and <code>User</code> class, we now want to map the two together.  That's where the SQLAlchemy ORM package comes in.  We'll use the <code>mapper</code> function to create a <strong>mapping</strong> between <code>users_table</code> and <code>User</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">mapper</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_enclosure">) </span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">.</span><span class="python_name">Mapper object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>The <code>mapper()</code> function creates a new <code>Mapper</code> object and stores it away for future reference.  It also <strong>instruments</strong> the attributes on our <code>User</code> class, corresponding to the <code>users_table</code> table.  The <code>id</code>, <code>name</code>, <code>fullname</code>, and <code>password</code> columns in our <code>users_table</code> are now instrumented upon our <code>User</code> class, meaning it will keep track of all changes to these attributes, and can save and load their values to/from the database.  Lets create our first user, 'Ed Jones', and ensure that the object has all three of these attributes:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ed_user </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">, </span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'edspassword'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ed_user</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">
</span><span class="python_literal">'ed'</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ed_user</span><span class="python_operator">.</span><span class="python_name">password</span><span class="python_operator">
</span><span class="python_literal">'edspassword'</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">str</span><span class="python_enclosure">(</span><span class="python_name">ed_user</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">'None'</span><span class="python_operator">
</span></pre>
    </div>
<p>What was that last <code>id</code> attribute?  That was placed there by the <code>Mapper</code>, to track the value of the <code>id</code> column in the <code>users_table</code>.  Since our <code>User</code> doesn't exist in the database, its id is <code>None</code>.  When we save the object, it will get populated automatically with its new id.
</p>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_too"></a>
    
    <div class="sectionL2">

    <h3>Too Verbose ?  There are alternatives</h3>
    
    

<p>The full set of steps to map a class, which are to define a <code>Table</code>, define a class, and then define a <code>mapper()</code>, are fairly verbose and for simple cases may appear overly disjoint.   Most popular object relational products use the so-called "active record" approach, where the table definition and its class mapping are all defined at once.  With SQLAlchemy, there are two excellent alternatives to its usual configuration which provide this approach:
</p>
<ul>
 <li>
     <a href='http://elixir.ematia.de/'>Elixir</a> is a "sister" product to SQLAlchemy, which is a full "declarative" layer built on top of SQLAlchemy.  It has existed almost as long as SA itself and defines a rich featureset on top of SA's normal configuration, adding many new capabilities such as plugins, automatic generation of table and column names based on configurations, and an intuitive system of defining relations.
 </li>

 <li>
     <a href="#plugins_declarative">declarative</a> is a so-called "micro-declarative" plugin included with SQLAlchemy 0.4.4 and above.  In contrast to Elixir, it maintains the use of the same configurational constructs outlined in this tutorial, except it allows the <code>Column</code>, <code>relation()</code>, and other constructs to be defined "inline" with the mapped class itself, so that explicit calls to <code>Table</code> and <code>mapper()</code> are not needed in most cases.
 </li>
</ul>
<p>With either declarative layer it's a good idea to be familiar with SQLAlchemy's "base" configurational style in any case.  But now that we have our configuration started, we're ready to look at how to build sessions and query the database; this process is the same regardless of configurational style.
</p>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_creating"></a>
    
    <div class="sectionL2">

    <h3>Creating a Session</h3>
    
    

<p>We're now ready to start talking to the database.  The ORM's "handle" to the database is the <code>Session</code>.  When we first set up the application, at the same level as our <code>create_engine()</code> statement, we define a second object called <code>Session</code> (or whatever you want to call it, <code>create_session</code>, etc.) which is configured by the <code>sessionmaker()</code> function.  This function is configurational and need only be called once.  <br></br>
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">sessionmaker</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_operator">, </span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>In the case where your application does not yet have an <code>Engine</code> when you define your module-level objects, just set it up like this:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Later, when you create your engine with <code>create_engine()</code>, connect it to the <code>Session</code> using <code>configure()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">configure</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_enclosure">)  </span><span class="python_comment"># once engine is available</span><span class="python_operator">
</span></pre>
    </div>
<p>This <code>Session</code> class will create new <code>Session</code> objects which are bound to our database and have the transactional characteristics we've configured.  Whenever you need to have a conversation with the database, you instantiate a <code>Session</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The above <code>Session</code> is associated with our SQLite <code>engine</code>, but it hasn't opened any connections yet.  When it's first used, it retrieves a connection from a pool of connections maintained by the <code>engine</code>, and holds onto it until we commit all changes and/or close the session object.  Because we configured <code>transactional=True</code>, there's also a transaction in progress (one notable exception to this is MySQL, when you use its default table style of MyISAM).  There's options available to modify this behavior but we'll go with this straightforward version to start.    <br></br>
</p>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_saving"></a>
    
    <div class="sectionL2">

    <h3>Saving Objects</h3>
    
    

<p>So saving our <code>User</code> is as easy as issuing <code>save()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">ed_user</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>But you'll notice nothing has happened yet.  Well, lets pretend something did, and try to query for our user.  This is done using the <code>query()</code> method on <code>Session</code>.  We create a new query representing the set of all <code>User</code> objects first.  Then we narrow the results by "filtering" down to the user we want; that is, the user whose <code>name</code> attribute is <code>&quot;ed&quot;</code>.  Finally we call <code>first()</code> which tells <code>Query</code>, "we'd like the first result in this list".
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_2', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">first</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_2_div" class="codepop" style="display:none;">BEGIN<br/>
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)<br/>
['ed', 'Ed Jones', 'edspassword']<br/>
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name = ? ORDER BY users.oid <br/>
 LIMIT 1 OFFSET 0<br/>
['ed']</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'edspassword'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>And we get back our new user.  If you view the generated SQL, you'll see that the <code>Session</code> issued an <code>INSERT</code> statement before querying.  The <code>Session</code> stores whatever you put into it in memory, and at certain points it issues a <strong>flush</strong>, which issues SQL to the database to store all pending new objects and changes to existing objects.  You can manually invoke the flush operation using <code>flush()</code>; however when the <code>Session</code> is configured to <code>autoflush</code>, it's usually not needed.
</p>
<p>OK, let's do some more operations.  We'll create and save three more users:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">, </span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'mary'</span><span class="python_operator">, </span><span class="python_literal">'Mary Contrary'</span><span class="python_operator">, </span><span class="python_literal">'xxg527'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'fred'</span><span class="python_operator">, </span><span class="python_literal">'Fred Flinstone'</span><span class="python_operator">, </span><span class="python_literal">'blah'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>Also, Ed has already decided his password isn't too secure, so lets change it:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ed_user</span><span class="python_operator">.</span><span class="python_name">password </span><span class="python_operator">= </span><span class="python_literal">'f8s7ccs'</span><span class="python_operator">
</span></pre>
    </div>
<p>Then we'll permanently store everything thats been changed and added to the database.  We do this via <code>commit()</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_3', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_3_div" class="codepop" style="display:none;">UPDATE users SET password=? WHERE users.id = ?<br/>
['f8s7ccs', 1]<br/>
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)<br/>
['wendy', 'Wendy Williams', 'foobar']<br/>
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)<br/>
['mary', 'Mary Contrary', 'xxg527']<br/>
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)<br/>
['fred', 'Fred Flinstone', 'blah']<br/>
COMMIT</div><pre><span class="python_operator"></span></pre>
    </div>
<p><code>commit()</code> flushes whatever remaining changes remain to the database, and commits the transaction.  The connection resources referenced by the session are now returned to the connection pool.  Subsequent operations with this session will occur in a <strong>new</strong> transaction, which will again re-acquire connection resources when first needed.
</p>
<p>If we look at Ed's <code>id</code> attribute, which earlier was <code>None</code>, it now has a value:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ed_user</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">
</span><span class="python_number">1</span><span class="python_operator">
</span></pre>
    </div>
<p>After each <code>INSERT</code> operation, the <code>Session</code> assigns all newly generated ids and column defaults to the mapped object instance.  For column defaults which are database-generated and are not part of the table's primary key, they'll be loaded when you first reference the attribute on the instance.
</p>
<p>One crucial thing to note about the <code>Session</code> is that each object instance is cached within the Session, based on its primary key identifier.  The reason for this cache is not as much for performance as it is for maintaining an <strong>identity map</strong> of instances.  This map guarantees that whenever you work with a particular <code>User</code> object in a session, <strong>you always get the same instance back</strong>.  As below, reloading Ed gives us the same instance back:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_4', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">ed_user </span><span class="python_keyword">is </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_4_div" class="codepop" style="display:none;">BEGIN<br/>
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name = ? ORDER BY users.oid <br/>
LIMIT 2 OFFSET 0<br/>
['ed']</div><pre><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>get()</code> method, which queries based on primary key, will not issue any SQL to the database if the given key is already present:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ed_user </span><span class="python_keyword">is </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_name">ed_user</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_querying"></a>
    
    <div class="sectionL2">

    <h3>Querying</h3>
    
    

<p>A whirlwind tour through querying.
</p>
<p>A <code>Query</code> is created from the <code>Session</code>, relative to a particular class we wish to load.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Once we have a query, we can start loading objects.  The Query object, when first created, represents all the instances of its main class.  You can iterate through it directly:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_5', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">user </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator"></span></pre><div id="popbox_5_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users ORDER BY users.oid<br/>
[]</div><pre><span class="python_name">ed</span><span class="python_operator">
</span><span class="python_name">wendy</span><span class="python_operator">
</span><span class="python_name">mary</span><span class="python_operator">
</span><span class="python_name">fred</span><span class="python_operator">
</span></pre>
    </div>
<p>...and the SQL will be issued at the point where the query is evaluated as a list.  If you apply array slices before iterating, LIMIT and OFFSET are applied to the query:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_6', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">u </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)[</span><span class="python_number">1</span><span class="python_operator">:</span><span class="python_number">3</span><span class="python_enclosure">]</span><span class="python_operator">: 
...    </span><span class="python_keyword">print </span><span class="python_name">u</span><span class="python_operator"></span></pre><div id="popbox_6_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users ORDER BY users.oid <br/>
LIMIT 2 OFFSET 1<br/>
[]</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">,</span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'mary'</span><span class="python_operator">,</span><span class="python_literal">'Mary Contrary'</span><span class="python_operator">, </span><span class="python_literal">'xxg527'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>Narrowing the results down is accomplished either with <code>filter_by()</code>, which uses keyword arguments:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_7', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">user </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_operator">, </span><span class="python_name">fullname</span><span class="python_operator">=</span><span class="python_literal">'Ed Jones'</span><span class="python_enclosure">)</span><span class="python_operator">:
...    </span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator"></span></pre><div id="popbox_7_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.fullname = ? AND users.name = ? ORDER BY users.oid<br/>
['Ed Jones', 'ed']</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>...or <code>filter()</code>, which uses SQL expression language constructs.  These allow you to use regular Python operators with the class-level attributes on your mapped class:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_8', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">user </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">:
...    </span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator"></span></pre><div id="popbox_8_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name = ? ORDER BY users.oid<br/>
['ed']</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>You can also use the <code>Column</code> constructs attached to the <code>users_table</code> object to construct SQL expressions:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_9', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">user </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">:
...    </span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator"></span></pre><div id="popbox_9_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name = ? ORDER BY users.oid<br/>
['ed']</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>Most common SQL operators are available, such as <code>LIKE</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_10', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%ed'</span><span class="python_enclosure">))[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator"> </span></pre><div id="popbox_10_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name LIKE ? ORDER BY users.oid <br/>
 LIMIT 1 OFFSET 1<br/>
['%ed']</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'fred'</span><span class="python_operator">,</span><span class="python_literal">'Fred Flinstone'</span><span class="python_operator">, </span><span class="python_literal">'blah'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>Note above our array index of <code>1</code> placed the appropriate LIMIT/OFFSET and returned a scalar result immediately.
</p>
<p>The <code>all()</code>, <code>one()</code>, and <code>first()</code> methods immediately issue SQL without using an iterative context or array index.  <code>all()</code> returns a list:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%ed'</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_11', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_11_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name LIKE ? ORDER BY users.oid<br/>
['%ed']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'fred'</span><span class="python_operator">,</span><span class="python_literal">'Fred Flinstone'</span><span class="python_operator">, </span><span class="python_literal">'blah'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p><code>first()</code> applies a limit of one and returns the first result as a scalar:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_12', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">first</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_12_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name LIKE ? ORDER BY users.oid <br/>
 LIMIT 1 OFFSET 0<br/>
['%ed']</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>and <code>one()</code>, applies a limit of <em>two</em>, and if not exactly one row returned (no more, no less), raises an error:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_13', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">try</span><span class="python_operator">:  
...     </span><span class="python_name">user </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">() </span><span class="python_operator">
... </span><span class="python_keyword">except </span><span class="python_name">Exception</span><span class="python_operator">, </span><span class="python_name">e</span><span class="python_operator">: 
...     </span><span class="python_keyword">print </span><span class="python_name">e</span><span class="python_operator"></span></pre><div id="popbox_13_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name LIKE ? ORDER BY users.oid <br/>
 LIMIT 2 OFFSET 0<br/>
['%ed']</div><pre><span class="python_name">Multiple rows returned </span><span class="python_keyword">for </span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>All <code>Query</code> methods that don't return a result instead return a new <code>Query</code> object, with modifications applied.  Therefore you can call many query methods successively to build up the criterion you want:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_14', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">&lt;</span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_operator">==</span><span class="python_literal">'Ed Jones'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_14_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.id &lt; ? AND users.name = ? AND users.fullname = ? ORDER BY users.oid<br/>
[2, 'ed', 'Ed Jones']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>If you need to use other conjunctions besides <code>AND</code>, all SQL conjunctions are available explicitly within expressions, such as <code>and_()</code> and <code>or_()</code>, when using <code>filter()</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">and_</span><span class="python_operator">, </span><span class="python_name">or_</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_15', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span>
<span class="python_operator">...    </span><span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">&lt;</span><span class="python_number">224</span><span class="python_operator">, </span><span class="python_name">or_</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'ed'</span><span class="python_operator">, </span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'wendy'</span><span class="python_enclosure">))</span>
<span class="python_operator">...    </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_15_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.id &lt; ? AND (users.name = ? OR users.name = ?) ORDER BY users.oid<br/>
[224, 'ed', 'wendy']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">,</span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>You also have full ability to use literal strings to construct SQL.  For a single criterion, use a string with <code>filter()</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_16', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">user </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_literal">"id&lt;224"</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator"></span></pre><div id="popbox_16_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE id&lt;224 ORDER BY users.oid<br/>
[]</div><pre><span class="python_name">ed</span><span class="python_operator">
</span><span class="python_name">wendy</span><span class="python_operator">
</span><span class="python_name">mary</span><span class="python_operator">
</span><span class="python_name">fred</span><span class="python_operator">
</span></pre>
    </div>
<p>Bind parameters can be specified with string-based SQL, using a colon.  To specify the values, use the <code>params()</code> method:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_17', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_literal">"id&lt;:value and name=:name"</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">params</span><span class="python_enclosure">(</span><span class="python_name">value</span><span class="python_operator">=</span><span class="python_number">224</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'fred'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_17_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE id&lt;? and name=? ORDER BY users.oid <br/>
LIMIT 2 OFFSET 0<br/>
[224, 'fred']</div><pre><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'fred'</span><span class="python_operator">,</span><span class="python_literal">'Fred Flinstone'</span><span class="python_operator">, </span><span class="python_literal">'blah'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>Note that when we use constructed SQL expressions, bind parameters are generated for us automatically; we don't need to worry about them.
</p>
<p>To use an entirely string-based statement, using <code>from_statement()</code>; just ensure that the columns clause of the statement contains the column names normally used by the mapper (below illustrated using an asterisk):
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_18', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">from_statement</span><span class="python_enclosure">(</span><span class="python_literal">"SELECT * FROM users where name=:name"</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">params</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_18_div" class="codepop" style="display:none;">SELECT * FROM users where name=?<br/>
['ed']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p><code>from_statement()</code> can also accomodate full <code>select()</code> constructs.  These are described in the <a href="#sql">SQL Expression Language Tutorial</a>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">select</span><span class="python_operator">, </span><span class="python_name">func</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_19', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">from_statement</span><span class="python_enclosure">(</span>
<span class="python_operator">...     </span><span class="python_name">select</span><span class="python_enclosure">(</span>
<span class="python_operator">...            </span><span class="python_enclosure">[</span><span class="python_name">users_table</span><span class="python_enclosure">]</span><span class="python_operator">, </span>
<span class="python_operator">...            </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">max</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">)])</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'maxuser'</span><span class="python_enclosure">)</span><span class="python_operator">==</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">) </span>
<span class="python_operator">...    </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_19_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE (SELECT max(users.name) AS max_1<br/>
FROM users) = users.name<br/>
[]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">,</span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>There's also a way to combine scalar results with objects, using <code>add_column()</code>.  This is often used for functions and aggregates.  When <code>add_column()</code> (or its cousin <code>add_entity()</code>, described later) is used, tuples are returned:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_20', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">r </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">add_column</span><span class="python_enclosure">(</span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">max</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">)])</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'maxuser'</span><span class="python_enclosure">))</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_name">r</span><span class="python_operator"> </span></pre><div id="popbox_20_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password, (SELECT max(users.name) AS max_1<br/>
FROM users) AS maxuser <br/>
FROM users ORDER BY users.oid<br/>
[]</div><pre><span class="python_enclosure">(</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'ed'</span><span class="python_operator">,</span><span class="python_literal">'Ed Jones'</span><span class="python_operator">, </span><span class="python_literal">'f8s7ccs'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, </span><span class="python_literal">u'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">,</span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, </span><span class="python_literal">u'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'mary'</span><span class="python_operator">,</span><span class="python_literal">'Mary Contrary'</span><span class="python_operator">, </span><span class="python_literal">'xxg527'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, </span><span class="python_literal">u'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'fred'</span><span class="python_operator">,</span><span class="python_literal">'Fred Flinstone'</span><span class="python_operator">, </span><span class="python_literal">'blah'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, </span><span class="python_literal">u'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_onetomany"></a>
    
    <div class="sectionL2">

    <h3>Building a One-to-Many Relation</h3>
    
    

<p>We've spent a lot of time dealing with just one class, and one table.  Let's now look at how SQLAlchemy deals with two tables, which have a relationship to each other.   Let's say that the users in our system also can store any number of email addresses associated with their username.  This implies a basic one to many association from the <code>users_table</code> to a new table which stores email addresses, which we will call <code>addresses</code>.  We will also create a relationship between this new table to the users table, using a <code>ForeignKey</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">ForeignKey</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">addresses_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email_address'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'users.id'</span><span class="python_enclosure">)))</span><span class="python_operator">
</span></pre>
    </div>
<p>Another call to <code>create_all()</code> will skip over our <code>users</code> table and build just the new <code>addresses</code> table:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_21', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator"> </span></pre><div id="popbox_21_div" class="codepop" style="display:none;">PRAGMA table_info(&quot;users&quot;)<br/>
{}<br/>
PRAGMA table_info(&quot;addresses&quot;)<br/>
{}<br/>
CREATE TABLE addresses (<br/>
    id INTEGER NOT NULL, <br/>
    email_address VARCHAR(100) NOT NULL, <br/>
    user_id INTEGER, <br/>
    PRIMARY KEY (id), <br/>
     FOREIGN KEY(user_id) REFERENCES users (id)<br/>
)<br/>
{}<br/>
COMMIT</div><pre><span class="python_operator"></span></pre>
    </div>
<p>For our ORM setup, we're going to start all over again.  We will first close out our <code>Session</code> and clear all <code>Mapper</code> objects:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">clear_mappers</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">clear_mappers</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Our <code>User</code> class, still around, reverts to being just a plain old class.  Lets create an <code>Address</code> class to represent a user's email address:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">class </span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">email_address</span><span class="python_enclosure">)</span><span class="python_operator">:
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">email_address </span><span class="python_operator">= </span><span class="python_name">email_address</span><span class="python_operator">
...
...     </span><span class="python_keyword">def </span><span class="python_name">__repr__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
...         </span><span class="python_keyword">return </span><span class="python_literal">"&lt;Address('%s')&gt;" </span><span class="python_operator">% </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">
</span></pre>
    </div>
<p>Now comes the fun part.  We define a mapper for each class, and associate them using a function called <code>relation()</code>.  We can define each mapper in any order we want:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">relation</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{    </span>
<span class="python_operator">...     </span><span class="python_literal">'addresses'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'user'</span><span class="python_enclosure">)</span>
<span class="python_operator">... </span><span class="python_enclosure">})</span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">.</span><span class="python_name">Mapper object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">) </span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">.</span><span class="python_name">Mapper object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>Above, the new thing we see is that <code>User</code> has defined a relation named <code>addresses</code>, which will reference a list of <code>Address</code> objects.  How does it know it's a list ?  SQLAlchemy figures it out for you, based on the foreign key relationship between <code>users_table</code> and <code>addresses_table</code>.  <br></br>
</p>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_relation_backref"></a>
    
    <div class="sectionL2">

    <h3>Working with Related Objects and Backreferences</h3>
    
    

<p>Now when we create a <code>User</code>, it automatically has this collection present:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">, </span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">
</span><span class="python_enclosure">[]</span><span class="python_operator">
</span></pre>
    </div>
<p>We are free to add <code>Address</code> objects, and the <code>session</code> will take care of everything for us.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">email_address</span><span class="python_operator">=</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">email_address</span><span class="python_operator">=</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>Before we save into the <code>Session</code>, lets examine one other thing that's happened here.  The <code>addresses</code> collection is present on our <code>User</code> because we added a <code>relation()</code> with that name.  But also within the <code>relation()</code> function is the keyword <code>backref</code>.  This keyword indicates that we wish to make a <strong>bi-directional relationship</strong>.  What this basically means is that not only did we generate a one-to-many relationship called <code>addresses</code> on the <code>User</code> class, we also generated a <strong>many-to-one</strong> relationship on the <code>Address</code> class.  This relationship is self-updating, without any data being flushed to the database, as we can see on one of Jack's addresses:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">
&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">.</span><span class="python_name">user</span><span class="python_operator">
&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>Let's save into the session, then close out the session and create a new one...so that we can see how <code>Jack</code> and his email addresses come back to us:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">jack</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_22', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_22_div" class="codepop" style="display:none;">BEGIN<br/>
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)<br/>
['jack', 'Jack Bean', 'gjffdd']<br/>
INSERT INTO addresses (email_address, user_id) VALUES (?, ?)<br/>
['jack@google.com', 5]<br/>
INSERT INTO addresses (email_address, user_id) VALUES (?, ?)<br/>
['j25@yahoo.com', 5]<br/>
COMMIT</div><pre><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Querying for Jack, we get just Jack back.  No SQL is yet issued for for Jack's addresses:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_23', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">jack </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_23_div" class="codepop" style="display:none;">BEGIN<br/>
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name = ? ORDER BY users.oid <br/>
 LIMIT 2 OFFSET 0<br/>
['jack']</div><pre><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">
&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span></pre>
    </div>
<p>Let's look at the <code>addresses</code> collection.  Watch the SQL:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_24', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator"></span></pre><div id="popbox_24_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE ? = addresses.user_id ORDER BY addresses.oid<br/>
[5]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>When we accessed the <code>addresses</code> collection, SQL was suddenly issued.  This is an example of a <strong>lazy loading relation</strong>.
</p>
<p>If you want to reduce the number of queries (dramatically, in many cases), we can apply an <strong>eager load</strong> to the query operation.  We clear out the session to ensure that a full reload occurs:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">clear</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Then apply an <strong>option</strong> to the query, indicating that we'd like <code>addresses</code> to load "eagerly".  SQLAlchemy then constructs a join between the <code>users</code> and <code>addresses</code> tables:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">eagerload</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_25', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">jack </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_25_div" class="codepop" style="display:none;">SELECT anon_1.users_id AS anon_1_users_id, anon_1.users_name AS anon_1_users_name, <br/>
anon_1.users_fullname AS anon_1_users_fullname, anon_1.users_password AS anon_1_users_password, <br/>
addresses_1.id AS addresses_1_id, addresses_1.email_address AS addresses_1_email_address, <br/>
addresses_1.user_id AS addresses_1_user_id <br/>
    FROM (SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, <br/>
    users.password AS users_password, users.oid AS users_oid <br/>
    FROM users <br/>
    WHERE users.name = ? ORDER BY users.oid <br/>
     LIMIT 2 OFFSET 0) AS anon_1 LEFT OUTER JOIN addresses AS addresses_1 <br/>
     ON anon_1.users_id = addresses_1.user_id ORDER BY anon_1.oid, addresses_1.oid<br/>
    ['jack']</div><pre><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">
&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>If you think that query is elaborate, it is !  But SQLAlchemy is just getting started.  Note that when using eager loading, <em>nothing</em> changes as far as the ultimate results returned.  The "loading strategy", as it's called, is designed to be completely transparent in all cases, and is for optimization purposes only.  Any query criterion you use to load objects, including ordering, limiting, other joins, etc., should return identical results regardless of the combination of lazily- and eagerly- loaded relationships present.
</p>
<p>An eagerload targeting across multiple relations can use dot separated names:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'orders'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'orders.items'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'orders.items.keywords'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>To roll up the above three individual <code>eagerload()</code> calls into one, use <code>eagerload_all()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload_all</span><span class="python_enclosure">(</span><span class="python_literal">'orders.items.keywords'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_joins"></a>
    
    <div class="sectionL2">

    <h3>Querying with Joins</h3>
    
    

<p>Which brings us to the next big topic.  What if we want to create joins that <em>do</em> change the results ?  For that, another <code>Query</code> tornado is coming....
</p>
<p>One way to join two tables together is just to compose a SQL expression.   Below we make one up using the <code>id</code> and <code>user_id</code> attributes on our mapped classes:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_26', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">.\
...         </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_26_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users, addresses <br/>
WHERE users.id = addresses.user_id AND addresses.email_address = ? ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>Or we can make a real JOIN construct; below we use the <code>join()</code> function available on <code>Table</code> to create a <code>Join</code> object, then tell the <code>Query</code> to use it as our FROM clause:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_27', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select_from</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">addresses_table</span><span class="python_enclosure">))</span><span class="python_operator">.\
...         </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_27_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users JOIN addresses ON users.id = addresses.user_id <br/>
WHERE addresses.email_address = ? ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that the <code>join()</code> construct has no problem figuring out the correct join condition between <code>users_table</code> and <code>addresses_table</code>..the <code>ForeignKey</code> we constructed says it all.
</p>
<p>The easiest way to join is automatically, using the <code>join()</code> method on <code>Query</code>.  Just give this method the path from A to B, using the name of a mapped relationship directly:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_28', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_28_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users JOIN addresses ON users.id = addresses.user_id <br/>
WHERE addresses.email_address = ? ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>By "A to B", we mean a single relation name or a path of relations.  In our case we only have <code>User-&gt;addresses-&gt;Address</code> configured, but if we had a setup like <code>A-&gt;bars-&gt;B-&gt;bats-&gt;C-&gt;widgets-&gt;D</code>, a join along all four entities would look like:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Foo</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">([</span><span class="python_literal">'bars'</span><span class="python_operator">, </span><span class="python_literal">'bats'</span><span class="python_operator">, </span><span class="python_literal">'widgets'</span><span class="python_enclosure">])</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_operator">...</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Each time <code>join()</code> is called on <code>Query</code>, the <strong>joinpoint</strong> of the query is moved to be that of the endpoint of the join.  As above, when we joined from <code>users_table</code> to <code>addresses_table</code>, all subsequent criterion used by <code>filter_by()</code> are against the <code>addresses</code> table.  When you <code>join()</code> again, the joinpoint starts back from the root.  We can also backtrack to the beginning explicitly using <code>reset_joinpoint()</code>.  This instruction will place the joinpoint back at the root <code>users</code> table, where subsequent <code>filter_by()</code> criterion are again against <code>users</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_29', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">email_address</span><span class="python_operator">=</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">reset_joinpoint</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_29_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users JOIN addresses ON users.id = addresses.user_id <br/>
WHERE addresses.email_address = ? AND users.name = ? ORDER BY users.oid<br/>
['jack@google.com', 'jack']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>In all cases, we can get the <code>User</code> and the matching <code>Address</code> objects back at the same time, by telling the session we want both.  This returns the results as a list of tuples:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_30', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">add_entity</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_30_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password, addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM users JOIN addresses ON users.id = addresses.user_id <br/>
WHERE addresses.email_address = ? ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[(</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Another common scenario is the need to join on the same table more than once.  For example, if we want to find a <code>User</code> who has two distinct email addresses, both <code>jack@google.com</code> as well as <code>j25@yahoo.com</code>, we need to join to the <code>Addresses</code> table twice.  SQLAlchemy does provide <code>Alias</code> objects which can accomplish this; but far easier is just to tell <code>join()</code> to alias for you:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_31', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_operator">, </span><span class="python_name">aliased</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...     </span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_operator">, </span><span class="python_name">aliased</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_31_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users JOIN addresses AS addresses_1 ON users.id = addresses_1.user_id JOIN addresses AS addresses_2 ON users.id = addresses_2.user_id <br/>
WHERE addresses_1.email_address = ? AND addresses_2.email_address = ? ORDER BY users.oid<br/>
['jack@google.com', 'j25@yahoo.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>The key thing which occurred above is that our SQL criterion were <strong>aliased</strong> as appropriate corresponding to the alias generated in the most recent <code>join()</code> call.
</p>
<p>The next section describes some "higher level" operators, including <code>any()</code> and <code>has()</code>, which make patterns like joining to multiple aliases unnecessary in most cases.
</p>


    
    <A name="datamapping_joins_relation"></a>
    
    <div class="sectionL3">

    <h3>Relation Operators</h3>
    
    

<p>A summary of all operators usable on relations:
</p>
<ul>
 <li><p>Filter on explicit column criterion, combined with a join.  Column criterion can make usage of all supported SQL operators and expression constructs:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_32', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_32_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users JOIN addresses ON users.id = addresses.user_id <br/>
WHERE addresses.email_address = ? ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>Criterion placed in <code>filter()</code> usually correspond to the last <code>join()</code> call; if the join was specified with <code>aliased=True</code>, class-level criterion against the join's target (or targets) will be appropriately aliased as well.  
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_33', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_operator">, </span><span class="python_name">aliased</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">.\
...    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_33_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users JOIN addresses AS addresses_1 ON users.id = addresses_1.user_id <br/>
WHERE addresses_1.email_address = ? ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Filter_by on key=value criterion, combined with a join.  Same as <code>filter()</code> on column criterion except keyword arguments are used.
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_34', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.\
...    </span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">email_address</span><span class="python_operator">=</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_34_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users JOIN addresses ON users.id = addresses.user_id <br/>
WHERE addresses.email_address = ? ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Filter on explicit column criterion using <code>any()</code> (for collections) or <code>has()</code> (for scalar relations).  This is a more succinct method than joining, as an <code>EXISTS</code> subquery is generated automatically.  <code>any()</code> means, "find all parent items where any child item of its collection meets this criterion":
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_35', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.\
...    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">any</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_35_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE EXISTS (SELECT 1 <br/>
FROM addresses <br/>
WHERE users.id = addresses.user_id AND addresses.email_address = ?) ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p><code>has()</code> means, "find all parent items where the child item meets this criterion":
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_36', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.\
...    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">has</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'jack'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_36_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE EXISTS (SELECT 1 <br/>
FROM users <br/>
WHERE users.id = addresses.user_id AND users.name = ?) ORDER BY addresses.oid<br/>
['jack']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>Both <code>has()</code> and <code>any()</code> also accept keyword arguments which are interpreted against the child classes' attributes:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_37', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.\
...    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">any</span><span class="python_enclosure">(</span><span class="python_name">email_address</span><span class="python_operator">=</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_37_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE EXISTS (SELECT 1 <br/>
FROM addresses <br/>
WHERE users.id = addresses.user_id AND addresses.email_address = ?) ORDER BY users.oid<br/>
['jack@google.com']</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Filter_by on instance identity criterion.  When comparing to a related instance, <code>filter_by()</code> will in most cases not need to reference the child table, since a child instance already contains enough information with which to generate criterion against the parent table.  <code>filter_by()</code> uses an equality comparison for all relationship types.  For many-to-one and one-to-one, this represents all objects which reference the given child object:
</p>

    

    <div class="code">
        <pre>
<span class="python_comment"># locate a user
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_38', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">user </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_38_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name = ? ORDER BY users.oid <br/>
LIMIT 2 OFFSET 0<br/>
['jack']</div><pre>

<span class="python_comment"># use the user in a filter_by() expression
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_39', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">user</span><span class="python_operator">=</span><span class="python_name">user</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_39_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE ? = addresses.user_id ORDER BY addresses.oid<br/>
[5]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>For one-to-many and many-to-many, it represents all objects which contain the given child object in the related collection:
</p>

    

    <div class="code">
        <pre>
<span class="python_comment"># locate an address
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_40', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">address </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.\
...    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_40_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE addresses.email_address = ? ORDER BY addresses.oid <br/>
LIMIT 2 OFFSET 0</div><pre><span class="python_enclosure">[</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">]</span><span class="python_operator">
</span>
<span class="python_comment"># use the address in a filter_by expression
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_41', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">=</span><span class="python_name">address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_41_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.id = ? ORDER BY users.oid<br/>
[5]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Select instances with a particular parent.  This is the "reverse" operation of filtering by instance identity criterion; the criterion is against a relation pointing <em>to</em> the desired class, instead of one pointing <em>from</em> it.  This will utilize the same "optimized" query criterion, usually not requiring any joins:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_42', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">with_parent</span><span class="python_enclosure">(</span><span class="python_name">user</span><span class="python_operator">, </span><span class="python_name">property</span><span class="python_operator">=</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_42_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE ? = addresses.user_id ORDER BY addresses.oid<br/>
[5]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Filter on a many-to-one/one-to-one instance identity criterion.  The class-level <code>==</code> operator will act the same as <code>filter_by()</code> for a scalar relation:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_43', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">user</span><span class="python_operator">==</span><span class="python_name">user</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_43_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE ? = addresses.user_id ORDER BY addresses.oid<br/>
[5]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>whereas the <code>!=</code> operator will generate a negated EXISTS clause:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_44', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">user</span><span class="python_operator">!=</span><span class="python_name">user</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_44_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE NOT (EXISTS (SELECT 1 <br/>
FROM users <br/>
WHERE users.id = addresses.user_id AND users.id = ?)) ORDER BY addresses.oid<br/>
[5]</div><pre><span class="python_enclosure">[]</span><span class="python_operator">
</span></pre>
    </div>
<p>a comparison to <code>None</code> also generates an IS NULL clause for a many-to-one relation:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_45', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">user</span><span class="python_operator">==</span><span class="python_name">None</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_45_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE addresses.user_id IS NULL ORDER BY addresses.oid<br/>
[]</div><pre><span class="python_enclosure">[]</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Filter on a one-to-many instance identity criterion.  The <code>contains()</code> operator returns all parent objects which contain the given object as one of its collection members:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_46', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">contains</span><span class="python_enclosure">(</span><span class="python_name">address</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_46_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.id = ? ORDER BY users.oid<br/>
[5]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Filter on a multiple one-to-many instance identity criterion.  The <code>==</code> operator can be used with a collection-based attribute against a list of items, which will generate multiple <code>EXISTS</code> clauses:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_47', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">addresses </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">user</span><span class="python_operator">==</span><span class="python_name">user</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_47_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE ? = addresses.user_id ORDER BY addresses.oid<br/>
[5]</div><pre>

<span class="python_literal"><a href="javascript:togglePopbox('popbox_48', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">addresses </span><span class="python_operator">== </span><span class="python_name">addresses</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_48_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE (EXISTS (SELECT 1 <br/>
FROM addresses <br/>
WHERE users.id = addresses.user_id AND addresses.id = ?)) AND (EXISTS (SELECT 1 <br/>
FROM addresses <br/>
WHERE users.id = addresses.user_id AND addresses.id = ?)) ORDER BY users.oid<br/>
[1, 2]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jack'</span><span class="python_operator">,</span><span class="python_literal">'Jack Bean'</span><span class="python_operator">, </span><span class="python_literal">'gjffdd'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>

 </li>
</ul>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="datamapping_deleting"></a>
    
    <div class="sectionL2">

    <h3>Deleting</h3>
    
    

<p>Let's try to delete <code>jack</code> and see how that goes.  We'll mark as deleted in the session, then we'll issue a <code>count</code> query to see that no rows remain:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">delete</span><span class="python_enclosure">(</span><span class="python_name">jack</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_49', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_49_div" class="codepop" style="display:none;">UPDATE addresses SET user_id=? WHERE addresses.id = ?<br/>
[None, 1]<br/>
UPDATE addresses SET user_id=? WHERE addresses.id = ?<br/>
[None, 2]<br/>
DELETE FROM users WHERE users.id = ?<br/>
[5]<br/>
SELECT count(users.id) AS count_1<br/>
FROM users <br/>
WHERE users.name = ?<br/>
['jack']</div><pre><span class="python_number">0</span><span class="python_operator">
</span></pre>
    </div>
<p>So far, so good.  How about Jack's <code>Address</code> objects ?
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_50', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span>
<span class="python_operator">...     </span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">in_</span><span class="python_enclosure">([</span><span class="python_literal">'jack@google.com'</span><span class="python_operator">, </span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">])</span>
<span class="python_operator">...  </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_50_div" class="codepop" style="display:none;">SELECT count(addresses.id) AS count_1<br/>
FROM addresses <br/>
WHERE addresses.email_address IN (?, ?)<br/>
['jack@google.com', 'j25@yahoo.com']</div><pre><span class="python_number">2</span><span class="python_operator">
</span></pre>
    </div>
<p>Uh oh, they're still there !  Analyzing the flush SQL, we can see that the <code>user_id</code> column of each address was set to NULL, but the rows weren't deleted.  SQLAlchemy doesn't assume that deletes cascade, you have to tell it so.
</p>
<p>So let's rollback our work, and start fresh with new mappers that express the relationship the way we want:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_51', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()  </span><span class="python_comment"># roll back the transaction</span><span class="python_operator"></span></pre><div id="popbox_51_div" class="codepop" style="display:none;">ROLLBACK</div><pre><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">clear</span><span class="python_enclosure">() </span><span class="python_comment"># clear the session</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">clear_mappers</span><span class="python_enclosure">() </span><span class="python_comment"># clear mappers</span><span class="python_operator">
</span></pre>
    </div>
<p>We need to tell the <code>addresses</code> relation on <code>User</code> that we'd like session.delete() operations to cascade down to the child <code>Address</code> objects.  Further, we also want <code>Address</code> objects which get detached from their parent <code>User</code>, whether or not the parent is deleted, to be deleted.  For these behaviors we use two <strong>cascade options</strong> <code>delete</code> and <code>delete-orphan</code>, using the string-based <code>cascade</code> option to the <code>relation()</code> function:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{    </span>
<span class="python_operator">...     </span><span class="python_literal">'addresses'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'user'</span><span class="python_operator">, </span><span class="python_name">cascade</span><span class="python_operator">=</span><span class="python_literal">"all, delete, delete-orphan"</span><span class="python_enclosure">)</span>
<span class="python_operator">... </span><span class="python_enclosure">})</span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">.</span><span class="python_name">Mapper object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">) </span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">.</span><span class="python_name">Mapper object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>Now when we load Jack, removing an address from his <code>addresses</code> collection will result in that <code>Address</code> being deleted:
</p>

    

    <div class="code">
        <pre>
<span class="python_comment"># load Jack by primary key
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_52', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">jack </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">    </span></pre><div id="popbox_52_div" class="codepop" style="display:none;">BEGIN<br/>
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.id = ?<br/>
[5]</div><pre>

<span class="python_comment"># remove one Address (lazy load fires off)
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_53', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">del </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">  </span></pre><div id="popbox_53_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE ? = addresses.user_id ORDER BY addresses.oid<br/>
[5]</div><pre>

<span class="python_comment"># only one address remains
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_54', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span>
<span class="python_operator">...     </span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">in_</span><span class="python_enclosure">([</span><span class="python_literal">'jack@google.com'</span><span class="python_operator">, </span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">])</span>
<span class="python_operator">... </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_54_div" class="codepop" style="display:none;">DELETE FROM addresses WHERE addresses.id = ?<br/>
[2]<br/>
SELECT count(addresses.id) AS count_1<br/>
FROM addresses <br/>
WHERE addresses.email_address IN (?, ?)<br/>
['jack@google.com', 'j25@yahoo.com']</div><pre><span class="python_number">1</span><span class="python_operator">
</span></pre>
    </div>
<p>Deleting Jack will delete both Jack and his remaining <code>Address</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">delete</span><span class="python_enclosure">(</span><span class="python_name">jack</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_55', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_55_div" class="codepop" style="display:none;">DELETE FROM addresses WHERE addresses.id = ?<br/>
[1]<br/>
DELETE FROM users WHERE users.id = ?<br/>
[5]<br/>
COMMIT</div><pre>

<span class="python_literal"><a href="javascript:togglePopbox('popbox_56', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_56_div" class="codepop" style="display:none;">BEGIN<br/>
SELECT count(users.id) AS count_1<br/>
FROM users <br/>
WHERE users.name = ?<br/>
['jack']</div><pre><span class="python_number">0</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_57', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span>
<span class="python_operator">...    </span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">in_</span><span class="python_enclosure">([</span><span class="python_literal">'jack@google.com'</span><span class="python_operator">, </span><span class="python_literal">'j25@yahoo.com'</span><span class="python_enclosure">])</span>
<span class="python_operator">... </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_57_div" class="codepop" style="display:none;">SELECT count(addresses.id) AS count_1<br/>
FROM addresses <br/>
WHERE addresses.email_address IN (?, ?)<br/>
['jack@google.com', 'j25@yahoo.com']</div><pre><span class="python_number">0</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_manytomany"></a>
    
    <div class="sectionL2">

    <h3>Building a Many To Many Relation</h3>
    
    

<p>We're moving into the bonus round here, but lets show off a many-to-many relationship.  We'll sneak in some other features too, just to take a tour.  We'll make our application a blog application, where users can write <code>BlogPost</code>s, which have <code>Keywords</code> associated with them.
</p>
<p>First some new tables:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">Text</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">post_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'posts'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'users.id'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'headline'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">255</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'body'</span><span class="python_operator">, </span><span class="python_name">Text</span><span class="python_enclosure">)</span>
<span class="python_operator">...        </span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">post_keywords </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'post_keywords'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'post_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'posts.id'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'keyword_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'keywords.id'</span><span class="python_enclosure">)))</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">keywords_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'keywords'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...        </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'keyword'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_operator">, </span><span class="python_name">unique</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_58', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator"> </span></pre><div id="popbox_58_div" class="codepop" style="display:none;">PRAGMA table_info(&quot;users&quot;)<br/>
{}<br/>
PRAGMA table_info(&quot;addresses&quot;)<br/>
{}<br/>
PRAGMA table_info(&quot;posts&quot;)<br/>
{}<br/>
PRAGMA table_info(&quot;keywords&quot;)<br/>
{}<br/>
PRAGMA table_info(&quot;post_keywords&quot;)<br/>
{}<br/>
CREATE TABLE posts (<br/>
    id INTEGER NOT NULL, <br/>
    user_id INTEGER, <br/>
    headline VARCHAR(255) NOT NULL, <br/>
    body TEXT, <br/>
    PRIMARY KEY (id), <br/>
     FOREIGN KEY(user_id) REFERENCES users (id)<br/>
)<br/>
{}<br/>
COMMIT<br/>
CREATE TABLE keywords (<br/>
    id INTEGER NOT NULL, <br/>
    keyword VARCHAR(50) NOT NULL, <br/>
    PRIMARY KEY (id), <br/>
     UNIQUE (keyword)<br/>
)<br/>
{}<br/>
COMMIT<br/>
CREATE TABLE post_keywords (<br/>
    post_id INTEGER, <br/>
    keyword_id INTEGER, <br/>
     FOREIGN KEY(post_id) REFERENCES posts (id), <br/>
     FOREIGN KEY(keyword_id) REFERENCES keywords (id)<br/>
)<br/>
{}<br/>
COMMIT</div><pre><span class="python_operator"></span></pre>
    </div>
<p>Then some classes:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">class </span><span class="python_name">BlogPost</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">headline</span><span class="python_operator">, </span><span class="python_name">body</span><span class="python_operator">, </span><span class="python_name">author</span><span class="python_enclosure">)</span><span class="python_operator">:
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">author </span><span class="python_operator">= </span><span class="python_name">author</span><span class="python_operator">
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">headline </span><span class="python_operator">= </span><span class="python_name">headline</span><span class="python_operator">
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">body </span><span class="python_operator">= </span><span class="python_name">body</span><span class="python_operator">
...     </span><span class="python_keyword">def </span><span class="python_name">__repr__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
...         </span><span class="python_keyword">return </span><span class="python_literal">"BlogPost(%r, %r, %r)" </span><span class="python_operator">% </span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">headline</span><span class="python_operator">, </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">body</span><span class="python_operator">, </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">author</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">class </span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">keyword</span><span class="python_enclosure">)</span><span class="python_operator">:
...         </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">keyword </span><span class="python_operator">= </span><span class="python_name">keyword</span><span class="python_operator">
</span></pre>
    </div>
<p>And the mappers.  <code>BlogPost</code> will reference <code>User</code> via its <code>author</code> attribute:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">backref</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_operator">, </span><span class="python_name">keywords_table</span><span class="python_enclosure">) </span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">.</span><span class="python_name">Mapper object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">BlogPost</span><span class="python_operator">, </span><span class="python_name">post_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{   </span>
<span class="python_operator">...    </span><span class="python_literal">'author'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_name">backref</span><span class="python_enclosure">(</span><span class="python_literal">'posts'</span><span class="python_operator">, </span><span class="python_name">lazy</span><span class="python_operator">=</span><span class="python_literal">'dynamic'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...    </span><span class="python_literal">'keywords'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_operator">, </span><span class="python_name">secondary</span><span class="python_operator">=</span><span class="python_name">post_keywords</span><span class="python_enclosure">)</span>
<span class="python_operator">... </span><span class="python_enclosure">}) </span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">.</span><span class="python_name">Mapper object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>There's three new things in the above mapper:
</p>
<ul>
 <li>
     the <code>User</code> relation has a backref, like we've used before, except this time it references a function called <code>backref()</code>.  This function is used when yo'd like to specify keyword options for the backwards relationship.
 </li>

 <li>
     the keyword option we specified to <code>backref()</code> is <code>lazy=&quot;dynamic&quot;</code>.  This sets a default <strong>loader strategy</strong> on the attribute, in this case a special strategy that allows partial loading of results.
 </li>

 <li>
     The <code>keywords</code> relation uses a keyword argument <code>secondary</code> to indicate the <strong>association table</strong> for the many to many relationship from <code>BlogPost</code> to <code>Keyword</code>.
 </li>
</ul>
<p>Usage is not too different from what we've been doing.  Let's give Wendy some blog posts:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_59', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">wendy </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_59_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users <br/>
WHERE users.name = ? ORDER BY users.oid <br/>
 LIMIT 2 OFFSET 0<br/>
['wendy']</div><pre><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">post </span><span class="python_operator">= </span><span class="python_name">BlogPost</span><span class="python_enclosure">(</span><span class="python_literal">"Wendy's Blog Post"</span><span class="python_operator">, </span><span class="python_literal">"This is a test"</span><span class="python_operator">, </span><span class="python_name">wendy</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">post</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>We're storing keywords uniquely in the database, but we know that we don't have any yet, so we can just create them:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">post</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">post</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_literal">'firstpost'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>We can now look up all blog posts with the keyword 'firstpost'.   We'll use a special collection operator <code>any</code> to locate "blog posts where any of its keywords has the keyword string 'firstpost'":
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_60', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">BlogPost</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">BlogPost</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">any</span><span class="python_enclosure">(</span><span class="python_name">keyword</span><span class="python_operator">=</span><span class="python_literal">'firstpost'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_60_div" class="codepop" style="display:none;">INSERT INTO keywords (keyword) VALUES (?)<br/>
['wendy']<br/>
INSERT INTO keywords (keyword) VALUES (?)<br/>
['firstpost']<br/>
INSERT INTO posts (user_id, headline, body) VALUES (?, ?, ?)<br/>
[2, &quot;Wendy's Blog Post&quot;, 'This is a test']<br/>
INSERT INTO post_keywords (post_id, keyword_id) VALUES (?, ?)<br/>
[[1, 1], [1, 2]]<br/>
SELECT posts.id AS posts_id, posts.user_id AS posts_user_id, posts.headline AS posts_headline, posts.body AS posts_body <br/>
FROM posts <br/>
WHERE EXISTS (SELECT 1 <br/>
FROM post_keywords, keywords <br/>
WHERE posts.id = post_keywords.post_id AND keywords.id = post_keywords.keyword_id AND keywords.keyword = ?) ORDER BY posts.oid<br/>
['firstpost']</div><pre><span class="python_enclosure">[</span><span class="python_name">BlogPost</span><span class="python_enclosure">(</span><span class="python_literal">"Wendy's Blog Post"</span><span class="python_operator">, </span><span class="python_literal">'This is a test'</span><span class="python_operator">, &lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">,</span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>If we want to look up just Wendy's posts, we can tell the query to narrow down to her as a parent:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_61', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">BlogPost</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">with_parent</span><span class="python_enclosure">(</span><span class="python_name">wendy</span><span class="python_enclosure">)</span><span class="python_operator">.\
... </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">BlogPost</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">any</span><span class="python_enclosure">(</span><span class="python_name">keyword</span><span class="python_operator">=</span><span class="python_literal">'firstpost'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_61_div" class="codepop" style="display:none;">SELECT posts.id AS posts_id, posts.user_id AS posts_user_id, posts.headline AS posts_headline, posts.body AS posts_body <br/>
FROM posts <br/>
WHERE ? = posts.user_id AND (EXISTS (SELECT 1 <br/>
FROM post_keywords, keywords <br/>
WHERE posts.id = post_keywords.post_id AND keywords.id = post_keywords.keyword_id AND keywords.keyword = ?)) ORDER BY posts.oid<br/>
[2, 'firstpost']</div><pre><span class="python_enclosure">[</span><span class="python_name">BlogPost</span><span class="python_enclosure">(</span><span class="python_literal">"Wendy's Blog Post"</span><span class="python_operator">, </span><span class="python_literal">'This is a test'</span><span class="python_operator">, &lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">,</span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Or we can use Wendy's own <code>posts</code> relation, which is a "dynamic" relation, to query straight from there:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_62', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">wendy</span><span class="python_operator">.</span><span class="python_name">posts</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">BlogPost</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">any</span><span class="python_enclosure">(</span><span class="python_name">keyword</span><span class="python_operator">=</span><span class="python_literal">'firstpost'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_62_div" class="codepop" style="display:none;">SELECT posts.id AS posts_id, posts.user_id AS posts_user_id, posts.headline AS posts_headline, posts.body AS posts_body <br/>
FROM posts <br/>
WHERE ? = posts.user_id AND (EXISTS (SELECT 1 <br/>
FROM post_keywords, keywords <br/>
WHERE posts.id = post_keywords.post_id AND keywords.id = post_keywords.keyword_id AND keywords.keyword = ?)) ORDER BY posts.oid<br/>
[2, 'firstpost']</div><pre><span class="python_enclosure">[</span><span class="python_name">BlogPost</span><span class="python_enclosure">(</span><span class="python_literal">"Wendy's Blog Post"</span><span class="python_operator">, </span><span class="python_literal">'This is a test'</span><span class="python_operator">, &lt;</span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'wendy'</span><span class="python_operator">,</span><span class="python_literal">'Wendy Williams'</span><span class="python_operator">, </span><span class="python_literal">'foobar'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#datamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="datamapping_further"></a>
    
    <div class="sectionL2">

    <h3>Further Reference</h3>
    
    

<p>Generated Documentation for Query: <a href="sqlalchemy_orm_query.html#docstrings_sqlalchemy.orm.query_Query">class Query(object)</a>
</p>
<p>ORM Generated Docs: <a href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm">module sqlalchemy.orm</a>
</p>
<p>Further information on mapping setups are in <a href="#advdatamapping">Mapper Configuration</a>.
</p>
<p>Further information on working with Sessions: <a href="#unitofwork">Using the Session</a>.
</p>




            <a href="#datamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    
    <A name="sql"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#datamapping">Object Relational Tutorial</a>

               |   
            Next: <a href="#advdatamapping">Mapper Configuration</a>
    </div>

        <h2>SQL Expression Language Tutorial</h2>
    </div>


        








    
    <A name="sql"></a>
    
    <div class="sectionL1">

    
    

<p>This tutorial will cover SQLAlchemy SQL Expressions, which are Python constructs that represent SQL statements.  The tutorial is in doctest format, meaning each <code>&gt;&gt;&gt;</code> line represents something you can type at a Python command prompt, and the following text represents the expected return value.  The tutorial has no prerequisites.
</p>


    
    <A name="sql_version"></a>
    
    <div class="sectionL2">

    <h3>Version Check</h3>
    
    

<p>A quick check to verify that we are on at least <strong>version 0.4</strong> of SQLAlchemy:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">__version__ </span><span class="python_operator">
</span><span class="python_number">0.4.0</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_connecting"></a>
    
    <div class="sectionL2">

    <h3>Connecting</h3>
    
    

<p>For this tutorial we will use an in-memory-only SQLite database.   This is an easy way to test things without needing to have an actual database defined anywhere.  To connect we use <code>create_engine()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">create_engine</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///:memory:'</span><span class="python_operator">, </span><span class="python_name">echo</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>echo</code> flag is a shortcut to setting up SQLAlchemy logging, which is accomplished via Python's standard <code>logging</code> module.  With it enabled, we'll see all the generated SQL produced.  If you are working through this tutorial and want less output generated, set it to <code>False</code>.   This tutorial will format the SQL behind a popup window so it doesn't get in our way; just click the "SQL" links to see whats being generated.
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_tables"></a>
    
    <div class="sectionL2">

    <h3>Define and Create Tables</h3>
    
    

<p>The SQL Expression Language constructs its expressions in most cases against table columns.  In SQLAlchemy, a column is most often represented by an object called <code>Column</code>, and in all cases a <code>Column</code> is associated with a <code>Table</code>.  A collection of <code>Table</code> objects and their associated child objects is referred to as <strong>database metadata</strong>.  In this tutorial we will explicitly lay out several <code>Table</code> objects, but note that SA can also "import" whole sets of <code>Table</code> objects automatically from an existing database (this process is called <strong>table reflection</strong>).
</p>
<p>We define our tables all within a catalog called <code>MetaData</code>, using the <code>Table</code> construct, which resembles regular SQL CREATE TABLE statements.  We'll make two tables, one of which represents "users" in an application, and another which represents zero or more "email addreses" for each row in the "users" table:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">Table</span><span class="python_operator">, </span><span class="python_name">Column</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_operator">, </span><span class="python_name">MetaData</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">metadata </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">users </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">40</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'fullname'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">... </span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">addresses </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
<span class="python_operator">...   </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...   </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">None</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'users.id'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...   </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email_address'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_operator">...  </span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>All about how to define <code>Table</code> objects, as well as how to create them from an existing database automatically, is described in <a href="#metadata">Database Meta Data</a>.
</p>
<p>Next, to tell the <code>MetaData</code> we'd actually like to create our selection of tables for real inside the SQLite database, we use <code>create_all()</code>, passing it the <code>engine</code> instance which points to our database.  This will check for the presence of each table first before creating, so it's safe to call multiple times:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_63', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator"> </span></pre><div id="popbox_63_div" class="codepop" style="display:none;">PRAGMA table_info(&quot;users&quot;)<br/>
{}<br/>
PRAGMA table_info(&quot;addresses&quot;)<br/>
{}<br/>
CREATE TABLE users (<br/>
    id INTEGER NOT NULL, <br/>
    name VARCHAR(40), <br/>
    fullname VARCHAR(100), <br/>
    PRIMARY KEY (id)<br/>
)<br/>
{}<br/>
COMMIT<br/>
CREATE TABLE addresses (<br/>
    id INTEGER NOT NULL, <br/>
    user_id INTEGER, <br/>
    email_address VARCHAR(50) NOT NULL, <br/>
    PRIMARY KEY (id), <br/>
     FOREIGN KEY(user_id) REFERENCES users (id)<br/>
)<br/>
{}<br/>
COMMIT</div><pre><span class="python_operator"></span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_insert"></a>
    
    <div class="sectionL2">

    <h3>Insert Expressions</h3>
    
    

<p>The first SQL expression we'll create is the <code>Insert</code> construct, which represents an INSERT statement.   This is typically created relative to its target table:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ins </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>To see a sample of the SQL this construct produces, use the <code>str()</code> function:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">str</span><span class="python_enclosure">(</span><span class="python_name">ins</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'</span><span class="python_operator">
</span></pre>
    </div>
<p>Notice above that the INSERT statement names every column in the <code>users</code> table.  This can be limited by using the <code>values</code> keyword, which establishes the VALUES clause of the INSERT explicitly:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ins </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">(</span><span class="python_name">values</span><span class="python_operator">=</span><span class="python_enclosure">{</span><span class="python_literal">'name'</span><span class="python_operator">:</span><span class="python_literal">'jack'</span><span class="python_operator">, </span><span class="python_literal">'fullname'</span><span class="python_operator">:</span><span class="python_literal">'Jack Jones'</span><span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">str</span><span class="python_enclosure">(</span><span class="python_name">ins</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, while the <code>values</code> keyword limited the VALUES clause to just two columns, the actual data we placed in <code>values</code> didn't get rendered into the string; instead we got named bind parameters.  As it turns out, our data <em>is</em> stored within our <code>Insert</code> construct, but it typically only comes out when the statement is actually executed; since the data consists of literal values, SQLAlchemy automatically generates bind parameters for them.  We can peek at this data for now by looking at the compiled form of the statement:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ins</span><span class="python_operator">.</span><span class="python_name">compile</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">params </span><span class="python_operator">
</span><span class="python_enclosure">{</span><span class="python_literal">'fullname'</span><span class="python_operator">: </span><span class="python_literal">'Jack Jones'</span><span class="python_operator">, </span><span class="python_literal">'name'</span><span class="python_operator">: </span><span class="python_literal">'jack'</span><span class="python_enclosure">}</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_executing"></a>
    
    <div class="sectionL2">

    <h3>Executing</h3>
    
    

<p>The interesting part of an <code>Insert</code> is executing it.  In this tutorial, we will generally focus on the most explicit method of executing a SQL construct, and later touch upon some "shortcut" ways to do it.  The <code>engine</code> object we created is a repository for database connections capable of issuing SQL to the database.  To acquire a connection, we use the <code>connect()</code> method:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">conn </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">conn </span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">Connection object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>The <code>Connection</code> object represents an actively checked out DBAPI connection resource.  Lets feed it our <code>Insert</code> object and see what happens:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">ins</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre><div class="codepop">INSERT INTO users (name, fullname) VALUES (?, ?)<br/>
['jack', 'Jack Jones']<br/>
COMMIT</div><pre>

<span class="python_operator"></span></pre>
    </div>
<p>So the INSERT statement was now issued to the database.  Although we got positional "qmark" bind parameters instead of "named" bind parameters in the output.  How come ?  Because when executed, the <code>Connection</code> used the SQLite <strong>dialect</strong> to help generate the statement; when we use the <code>str()</code> function, the statement isn't aware of this dialect, and falls back onto a default which uses named parameters. We can view this manually as follows:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ins</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">str</span><span class="python_enclosure">(</span><span class="python_name">ins</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">'INSERT INTO users (name, fullname) VALUES (?, ?)'</span><span class="python_operator">
</span></pre>
    </div>
<p>What about the <code>result</code> variable we got when we called <code>execute()</code> ?  As the SQLAlchemy <code>Connection</code> object references a DBAPI connection, the result, known as a <code>ResultProxy</code> object, is analogous to the DBAPI cursor object.  In the case of an INSERT, we can get important information from it, such as the primary key values which were generated from our statement:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">result</span><span class="python_operator">.</span><span class="python_name">last_inserted_ids</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>The value of <code>1</code> was automatically generated by SQLite, but only because we did not specify the <code>id</code> column in our <code>Insert</code> statement; otherwise, our explicit value would have been used.   In either case, SQLAlchemy always knows how to get at a newly generated primary key value, even though the method of generating them is different across different databases; each databases' <code>Dialect</code> knows the specific steps needed to determine the correct value (or values; note that <code>last_inserted_ids()</code> returns a list so that it supports composite primary keys).
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_execmany"></a>
    
    <div class="sectionL2">

    <h3>Executing Multiple Statements</h3>
    
    

<p>Our insert example above was intentionally a little drawn out to show some various behaviors of expression language constructs.  In the usual case, an <code>Insert</code> statement is usually compiled against the parameters sent to the <code>execute()</code> method on <code>Connection</code>, so that there's no need to use the <code>values</code> keyword with <code>Insert</code>.  Lets create a generic <code>Insert</code> statement again and use it in the "normal" way:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">ins </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">ins</span><span class="python_operator">, </span><span class="python_name">id</span><span class="python_operator">=</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'wendy'</span><span class="python_operator">, </span><span class="python_name">fullname</span><span class="python_operator">=</span><span class="python_literal">'Wendy Williams'</span><span class="python_enclosure">) </span><span class="python_operator">
</span></pre><div class="codepop">INSERT INTO users (id, name, fullname) VALUES (?, ?, ?)<br/>
[2, 'wendy', 'Wendy Williams']<br/>
COMMIT</div><pre>

<span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>Above, because we specified all three columns in the the <code>execute()</code> method, the compiled <code>Insert</code> included all three columns.  The <code>Insert</code> statement is compiled at execution time based on the parameters we specified; if we specified fewer parameters, the <code>Insert</code> would have fewer entries in its VALUES clause.
</p>
<p>To issue many inserts using DBAPI's <code>executemany()</code> method, we can send in a list of dictionaries each containing a distinct set of parameters to be inserted, as we do here to add some email addresses:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">()</span><span class="python_operator">, </span><span class="python_enclosure">[ </span>
<span class="python_operator">...    </span><span class="python_enclosure">{</span><span class="python_literal">'user_id'</span><span class="python_operator">: </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">'email_address' </span><span class="python_operator">: </span><span class="python_literal">'jack@yahoo.com'</span><span class="python_enclosure">}</span><span class="python_operator">,</span>
<span class="python_operator">...    </span><span class="python_enclosure">{</span><span class="python_literal">'user_id'</span><span class="python_operator">: </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">'email_address' </span><span class="python_operator">: </span><span class="python_literal">'jack@msn.com'</span><span class="python_enclosure">}</span><span class="python_operator">,</span>
<span class="python_operator">...    </span><span class="python_enclosure">{</span><span class="python_literal">'user_id'</span><span class="python_operator">: </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">'email_address' </span><span class="python_operator">: </span><span class="python_literal">'www@www.org'</span><span class="python_enclosure">}</span><span class="python_operator">,</span>
<span class="python_operator">...    </span><span class="python_enclosure">{</span><span class="python_literal">'user_id'</span><span class="python_operator">: </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">'email_address' </span><span class="python_operator">: </span><span class="python_literal">'wendy@aol.com'</span><span class="python_enclosure">}</span><span class="python_operator">,</span>
<span class="python_operator">... </span><span class="python_enclosure">])</span><span class="python_operator">
</span></pre><div class="codepop">INSERT INTO addresses (user_id, email_address) VALUES (?, ?)<br/>
[[1, 'jack@yahoo.com'], [1, 'jack@msn.com'], [2, 'www@www.org'], [2, 'wendy@aol.com']]<br/>
COMMIT</div><pre>

<span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>Above, we again relied upon SQLite's automatic generation of primary key identifiers for each <code>addresses</code> row.
</p>
<p>When executing multiple sets of parameters, each dictionary must have the <strong>same</strong> set of keys; i.e. you cant have fewer keys in some dictionaries than others.  This is because the <code>Insert</code> statement is compiled against the <strong>first</strong> dictionary in the list, and it's assumed that all subsequent argument dictionaries are compatible with that statement.
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_connectionless"></a>
    
    <div class="sectionL2">

    <h3>Connectionless / Implicit Execution</h3>
    
    

<p>We're executing our <code>Insert</code> using a <code>Connection</code>.  There's two options that allow you to not have to deal with the connection part.  You can execute in the <strong>connectionless</strong> style, using the engine, which opens and closes a connection for you:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_64', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">()</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'fred'</span><span class="python_operator">, </span><span class="python_name">fullname</span><span class="python_operator">=</span><span class="python_literal">"Fred Flintstone"</span><span class="python_enclosure">)</span><span class="python_operator"></span></pre><div id="popbox_64_div" class="codepop" style="display:none;">INSERT INTO users (name, fullname) VALUES (?, ?)<br/>
['fred', 'Fred Flintstone']<br/>
COMMIT</div><pre><span class="python_operator"></span></pre>
    </div>
<p>and you can save even more steps than that, if you connect the <code>Engine</code> to the <code>MetaData</code> object we created earlier.  When this is done, all SQL expressions which involve tables within the <code>MetaData</code> object will be automatically <strong>bound</strong> to the <code>Engine</code>.  In this case, we call it  <strong>implicit execution</strong>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_65', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">"mary"</span><span class="python_operator">, </span><span class="python_name">fullname</span><span class="python_operator">=</span><span class="python_literal">"Mary Contrary"</span><span class="python_enclosure">)</span><span class="python_operator"></span></pre><div id="popbox_65_div" class="codepop" style="display:none;">INSERT INTO users (name, fullname) VALUES (?, ?)<br/>
['mary', 'Mary Contrary']<br/>
COMMIT</div><pre><span class="python_operator"></span></pre>
    </div>
<p>When the <code>MetaData</code> is bound, statements will also compile against the engine's dialect.  Since a lot of the examples here assume the default dialect, we'll detach the engine from the metadata which we just attached:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">None</span><span class="python_operator">
</span></pre>
    </div>
<p>Detailed examples of connectionless and implicit execution are available in the "Engines" chapter: <a href="#dbengine_implicit">Connectionless Execution, Implicit Execution</a>.
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_selecting"></a>
    
    <div class="sectionL2">

    <h3>Selecting</h3>
    
    

<p>We began with inserts just so that our test database had some data in it.  The more interesting part of the data is selecting it !  We'll cover UPDATE and DELETE statements later.  The primary construct used to generate SELECT statements is the <code>select()</code> function:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">select</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_enclosure">])</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator"></span></pre><div class="codepop">SELECT users.id, users.name, users.fullname <br/>
FROM users<br/>
[]</div><pre>

<span class="python_operator"></span></pre>
    </div>
<p>Above, we issued a basic <code>select()</code> call, placing the <code>users</code> table within the COLUMNS clause of the select, and then executing.  SQLAlchemy expanded the <code>users</code> table into the set of each of its columns, and also generated a FROM clause for us.  The result returned is again a <code>ResultProxy</code> object, which acts much like a DBAPI cursor, including methods such as <code>fetchone()</code> and <code>fetchall()</code>.  The easiest way to get rows from it is to just iterate:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_name">row</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_literal">u'Fred Flintstone'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_literal">u'Mary Contrary'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, we see that printing each row produces a simple tuple-like result.  We have more options at accessing the data in each row.  One very common way is through dictionary access, using the string names of columns:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_66', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator"></span></pre><div id="popbox_66_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname <br/>
FROM users<br/>
[]</div><pre><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">row </span><span class="python_operator">= </span><span class="python_name">result</span><span class="python_operator">.</span><span class="python_name">fetchone</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_literal">"name:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_literal">'name'</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_literal">"; fullname:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_literal">'fullname'</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_name">name</span><span class="python_operator">: </span><span class="python_name">jack </span><span class="python_operator">; </span><span class="python_name">fullname</span><span class="python_operator">: </span><span class="python_name">Jack Jones</span><span class="python_operator">
</span></pre>
    </div>
<p>Integer indexes work as well:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">row </span><span class="python_operator">= </span><span class="python_name">result</span><span class="python_operator">.</span><span class="python_name">fetchone</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_literal">"name:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_literal">"; fullname:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_number">2</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_name">name</span><span class="python_operator">: </span><span class="python_name">wendy </span><span class="python_operator">; </span><span class="python_name">fullname</span><span class="python_operator">: </span><span class="python_name">Wendy Williams</span><span class="python_operator">
</span></pre>
    </div>
<p>But another way, whose usefulness will become apparent later on, is to use the <code>Column</code> objects directly as keys:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_67', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_literal">"name:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_literal">"; fullname:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_enclosure">]</span><span class="python_operator"></span></pre><div id="popbox_67_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname <br/>
FROM users<br/>
[]</div><pre><span class="python_name">name</span><span class="python_operator">: </span><span class="python_name">jack </span><span class="python_operator">; </span><span class="python_name">fullname</span><span class="python_operator">: </span><span class="python_name">Jack Jones</span><span class="python_operator">
</span><span class="python_name">name</span><span class="python_operator">: </span><span class="python_name">wendy </span><span class="python_operator">; </span><span class="python_name">fullname</span><span class="python_operator">: </span><span class="python_name">Wendy Williams</span><span class="python_operator">
</span><span class="python_name">name</span><span class="python_operator">: </span><span class="python_name">fred </span><span class="python_operator">; </span><span class="python_name">fullname</span><span class="python_operator">: </span><span class="python_name">Fred Flintstone</span><span class="python_operator">
</span><span class="python_name">name</span><span class="python_operator">: </span><span class="python_name">mary </span><span class="python_operator">; </span><span class="python_name">fullname</span><span class="python_operator">: </span><span class="python_name">Mary Contrary</span><span class="python_operator">
</span></pre>
    </div>
<p>Result sets which have pending rows remaining should be explicitly closed before discarding.  While the resources referenced by the <code>ResultProxy</code> will be closed when the object is garbage collected, it's better to make it explicit as some database APIs are very picky about such things:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">result</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>If we'd like to more carefully control the columns which are placed in the COLUMNS clause of the select, we reference individual <code>Column</code> objects from our <code>Table</code>.  These are available as named attributes off the <code>c</code> attribute of the <code>Table</code> object:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_enclosure">])</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_68', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator"></span></pre><div id="popbox_68_div" class="codepop" style="display:none;">SELECT users.name, users.fullname <br/>
FROM users<br/>
[]</div><pre><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:  
...     </span><span class="python_keyword">print </span><span class="python_name">row</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_literal">u'Fred Flintstone'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_literal">u'Mary Contrary'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Lets observe something interesting about the FROM clause.  Whereas the generated statement contains two distinct sections, a "SELECT columns" part and a "FROM table" part, our <code>select()</code> construct only has a list containing columns.  How does this work ?  Let's try putting <em>two</em> tables into our <code>select()</code> statement:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_69', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_enclosure">]))</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_name">row</span><span class="python_operator"></span></pre><div id="popbox_69_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname, addresses.id, addresses.user_id, addresses.email_address <br/>
FROM users, addresses<br/>
[]</div><pre><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'www@www.org'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy@aol.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_operator">, </span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'www@www.org'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy@aol.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_literal">u'Fred Flintstone'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_literal">u'Fred Flintstone'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_literal">u'Fred Flintstone'</span><span class="python_operator">, </span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'www@www.org'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_literal">u'Fred Flintstone'</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy@aol.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_literal">u'Mary Contrary'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_literal">u'Mary Contrary'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_literal">u'Mary Contrary'</span><span class="python_operator">, </span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'www@www.org'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_literal">u'Mary Contrary'</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy@aol.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>It placed <strong>both</strong> tables into the FROM clause.  But also, it made a real mess.  Those who are familiar with SQL joins know that this is a <strong>Cartesian product</strong>; each row from the <code>users</code> table is produced against each row from the <code>addresses</code> table.  So to put some sanity into this statement, we need a WHERE clause.  Which brings us to the second argument of <code>select()</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_70', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_name">row</span><span class="python_operator"></span></pre><div id="popbox_70_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname, addresses.id, addresses.user_id, addresses.email_address <br/>
FROM users, addresses <br/>
WHERE users.id = addresses.user_id<br/>
[]</div><pre><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_operator">, </span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'www@www.org'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy@aol.com'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>So that looks a lot better, we added an expression to our <code>select()</code> which had the effect of adding <code>WHERE users.id = addresses.user_id</code> to our statement, and our results were managed down so that the join of <code>users</code> and <code>addresses</code> rows made sense.  But let's look at that expression?  It's using just a Python equality operator between two different <code>Column</code> objects.  It should be clear that something is up.  Saying <code>1==1</code> produces <code>True</code>, and <code>1==2</code> produces <code>False</code>, not a WHERE clause.  So lets see exactly what that expression is doing:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id </span><span class="python_operator">
&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql</span><span class="python_operator">.</span><span class="python_name">expression</span><span class="python_operator">.</span><span class="python_name">_BinaryExpression object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>
<p>Wow, surprise !  This is neither a <code>True</code> nor a <code>False</code>.  Well what is it ?
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">str</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">'users.id = addresses.user_id'</span><span class="python_operator">
</span></pre>
    </div>
<p>As you can see, the <code>==</code> operator is producing an object that is very much like the <code>Insert</code> and <code>select()</code> objects we've made so far, thanks to Python's <code>__eq__()</code> builtin; you call <code>str()</code> on it and it produces SQL.  By now, one can that everything we are working with is ultimately the same type of object.  SQLAlchemy terms the base class of all of these expressions as <code>sqlalchemy.sql.ClauseElement</code>.
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_operators"></a>
    
    <div class="sectionL2">

    <h3>Operators</h3>
    
    

<p>Since we've stumbled upon SQLAlchemy's operator paradigm, let's go through some of its capabilities.  We've seen how to equate two columns to each other:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">
</span></pre>
    </div>
<p>If we use a literal value (a literal meaning, not a SQLAlchemy clause object), we get a bind parameter:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_number">7</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= :</span><span class="python_name">users_id_1</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>7</code> literal is embedded in <code>ClauseElement</code>; we can use the same trick we did with the <code>Insert</code> object to see it:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_number">7</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">compile</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">params</span><span class="python_operator">
</span><span class="python_enclosure">{</span><span class="python_literal">'users_id_1'</span><span class="python_operator">: </span><span class="python_number">7</span><span class="python_enclosure">}</span><span class="python_operator">
</span></pre>
    </div>
<p>Most Python operators, as it turns out, produce a SQL expression here, like equals, not equals, etc.:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">!= </span><span class="python_number">7</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">!= :</span><span class="python_name">users_id_1</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># None converts to IS NULL</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">== </span><span class="python_name">None</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name IS NULL</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># reverse works too </span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_literal">'fred' </span><span class="python_operator">&gt; </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">&lt; :</span><span class="python_name">users_name_1</span><span class="python_operator">
</span></pre>
    </div>
<p>If we add two integer columns together, we get an addition expression:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">+ </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">+ </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">
</span></pre>
    </div>
<p>Interestingly, the type of the <code>Column</code> is important !  If we use <code>+</code> with two string based columns (recall we put types like <code>Integer</code> and <code>String</code> on our <code>Column</code> objects at the beginning), we get something different:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">+ </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">|| </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_operator">
</span></pre>
    </div>
<p>Where <code>||</code> is the string concatenation operator used on most databases.  But not all of them.  MySQL users, fear not:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">+ </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">compile</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'mysql://'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_name">concat</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The above illustrates the SQL that's generated for an <code>Engine</code> that's connected to a MySQL database; the <code>||</code> operator now compiles as MySQL's <code>concat()</code> function.
</p>
<p>If you have come across an operator which really isn't available, you can always use the <code>op()</code> method; this generates whatever operator you need:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">op</span><span class="python_enclosure">(</span><span class="python_literal">'tiddlywinks'</span><span class="python_enclosure">)(</span><span class="python_literal">'foo'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name tiddlywinks </span><span class="python_operator">:</span><span class="python_name">users_name_1</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_conjunctions"></a>
    
    <div class="sectionL2">

    <h3>Conjunctions</h3>
    
    

<p>We'd like to show off some of our operators inside of <code>select()</code> constructs.  But we need to lump them together a little more, so let's first introduce some conjunctions.  Conjunctions are those little words like AND and OR that put things together.  We'll also hit upon NOT.  AND, OR and NOT can work from the corresponding functions SQLAlchemy provides (notice we also throw in a LIKE):
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">and_</span><span class="python_operator">, </span><span class="python_name">or_</span><span class="python_operator">, </span><span class="python_name">not_</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'j%'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
<span class="python_operator">...     </span><span class="python_name">or_</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'wendy@aol.com'</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...     </span><span class="python_name">not_</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">&gt;</span><span class="python_number">5</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name LIKE </span><span class="python_operator">:</span><span class="python_name">users_name_1 AND users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id AND </span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">email_address </span><span class="python_operator">= :</span><span class="python_name">addresses_email_address_1 OR addresses</span><span class="python_operator">.</span><span class="python_name">email_address </span><span class="python_operator">= :</span><span class="python_name">addresses_email_address_2</span><span class="python_enclosure">) </span><span class="python_operator">
</span><span class="python_name">AND users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">&lt;= :</span><span class="python_name">users_id_1</span><span class="python_operator">
</span></pre>
    </div>
<p>And you can also use the re-jiggered bitwise AND, OR and NOT operators, although because of Python operator precedence you have to watch your parenthesis:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'j%'</span><span class="python_enclosure">) </span><span class="python_operator">&amp; </span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">) </span><span class="python_operator">&amp;  \
...     </span><span class="python_enclosure">((</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'wendy@aol.com'</span><span class="python_enclosure">) </span><span class="python_operator">| </span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@yahoo.com'</span><span class="python_enclosure">))</span><span class="python_operator"> \
...     &amp; ~</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">&gt;</span><span class="python_number">5</span><span class="python_enclosure">) </span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name LIKE </span><span class="python_operator">:</span><span class="python_name">users_name_1 AND users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id AND </span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">email_address </span><span class="python_operator">= :</span><span class="python_name">addresses_email_address_1 OR addresses</span><span class="python_operator">.</span><span class="python_name">email_address </span><span class="python_operator">= :</span><span class="python_name">addresses_email_address_2</span><span class="python_enclosure">) </span><span class="python_operator">
</span><span class="python_name">AND users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">&lt;= :</span><span class="python_name">users_id_1</span><span class="python_operator">
</span></pre>
    </div>
<p>So with all of this vocabulary, let's select all users who have an email address at AOL or MSN, whose name starts with a letter between "m" and "z", and we'll also generate a column containing their full name combined with their email address.  We will add two new constructs to this statement, <code>between()</code> and <code>label()</code>.  <code>between()</code> produces a BETWEEN clause, and <code>label()</code> is used in a column expression to produce labels using the <code>AS</code> keyword; it's recommended when selecting from expressions that otherwise would not have a name:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">+ </span><span class="python_literal">", " </span><span class="python_operator">+ </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'title'</span><span class="python_enclosure">)]</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">and_</span><span class="python_enclosure">( </span>
<span class="python_operator">...            </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
<span class="python_operator">...            </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">between</span><span class="python_enclosure">(</span><span class="python_literal">'m'</span><span class="python_operator">, </span><span class="python_literal">'z'</span><span class="python_enclosure">)</span><span class="python_operator">, </span>
<span class="python_operator">...           </span><span class="python_name">or_</span><span class="python_enclosure">(</span>
<span class="python_operator">...              </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%@aol.com'</span><span class="python_enclosure">)</span><span class="python_operator">, </span>
<span class="python_operator">...              </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%@msn.com'</span><span class="python_enclosure">)</span>
<span class="python_operator">...           </span><span class="python_enclosure">)</span>
<span class="python_operator">...        </span><span class="python_enclosure">)</span>
<span class="python_operator">...    </span><span class="python_enclosure">) </span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">() </span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">|| ? || </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">email_address AS title </span><span class="python_operator">
</span><span class="python_name">FROM users</span><span class="python_operator">, </span><span class="python_name">addresses </span><span class="python_operator">
</span><span class="python_name">WHERE users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id AND users</span><span class="python_operator">.</span><span class="python_name">name BETWEEN</span><span class="python_operator"> ? </span><span class="python_name">AND</span><span class="python_operator"> ? </span><span class="python_name">AND </span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">email_address LIKE</span><span class="python_operator"> ? </span><span class="python_name">OR addresses</span><span class="python_operator">.</span><span class="python_name">email_address LIKE</span><span class="python_operator"> ?</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_literal">', '</span><span class="python_operator">, </span><span class="python_literal">'m'</span><span class="python_operator">, </span><span class="python_literal">'z'</span><span class="python_operator">, </span><span class="python_literal">'%@aol.com'</span><span class="python_operator">, </span><span class="python_literal">'%@msn.com'</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_enclosure">[(</span><span class="python_literal">u'Wendy Williams, wendy@aol.com'</span><span class="python_operator">,</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Once again, SQLAlchemy figured out the FROM clause for our statement.  In fact it will determine the FROM clause based on all of its other bits; the columns clause, the whereclause, and also some other elements which we haven't covered yet, which include ORDER BY, GROUP BY, and HAVING. 
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_text"></a>
    
    <div class="sectionL2">

    <h3>Using Text</h3>
    
    

<p>Our last example really became a handful to type.  Going from what one understands to be a textual SQL expression into a Python construct which groups components together in a programmatic style can be hard.  That's why SQLAlchemy lets you just use strings too.  The <code>text()</code> construct represents any textual statement.  To use bind parameters with <code>text()</code>, always use the named colon format.  Such as below, we create a <code>text()</code> and execute it, feeding in the bind parameters to the <code>execute()</code> method:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">text</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">text</span><span class="python_enclosure">(</span><span class="python_literal">"""SELECT users.fullname || ', ' || addresses.email_address AS title 
...            FROM users, addresses 
...            WHERE users.id = addresses.user_id AND users.name BETWEEN :x AND :y AND 
...            (addresses.email_address LIKE :e1 OR addresses.email_address LIKE :e2)
...        """</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_71', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_operator">, </span><span class="python_name">x</span><span class="python_operator">=</span><span class="python_literal">'m'</span><span class="python_operator">, </span><span class="python_name">y</span><span class="python_operator">=</span><span class="python_literal">'z'</span><span class="python_operator">, </span><span class="python_name">e1</span><span class="python_operator">=</span><span class="python_literal">'%@aol.com'</span><span class="python_operator">, </span><span class="python_name">e2</span><span class="python_operator">=</span><span class="python_literal">'%@msn.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_71_div" class="codepop" style="display:none;">SELECT users.fullname || ', ' || addresses.email_address AS title <br/>
FROM users, addresses <br/>
WHERE users.id = addresses.user_id AND users.name BETWEEN ? AND ? AND <br/>
(addresses.email_address LIKE ? OR addresses.email_address LIKE ?)<br/>
['m', 'z', '%@aol.com', '%@msn.com']</div><pre><span class="python_enclosure">[(</span><span class="python_literal">u'Wendy Williams, wendy@aol.com'</span><span class="python_operator">,</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>To gain a "hybrid" approach, any of SA's SQL constructs can have text freely intermingled wherever you like - the <code>text()</code> construct can be placed within any other <code>ClauseElement</code> construct, and when used in a non-operator context, a direct string may be placed which converts to <code>text()</code> automatically.  Below we combine the usage of <code>text()</code> and strings with our constructed <code>select()</code> object, by using the <code>select()</code> object to structure the statement, and the <code>text()</code>/strings to provide all the content within the structure.  For this example, SQLAlchemy is not given any <code>Column</code> or <code>Table</code> objects in any of its expressions, so it cannot generate a FROM clause.  So we also give it the <code>from_obj</code> keyword argument, which is a list of <code>ClauseElements</code> (or strings) to be placed within the FROM clause:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">text</span><span class="python_enclosure">(</span><span class="python_literal">"users.fullname || ', ' || addresses.email_address AS title"</span><span class="python_enclosure">)]</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">and_</span><span class="python_enclosure">( </span>
<span class="python_operator">...            </span><span class="python_literal">"users.id = addresses.user_id"</span><span class="python_operator">, </span>
<span class="python_operator">...             </span><span class="python_literal">"users.name BETWEEN 'm' AND 'z'"</span><span class="python_operator">,</span>
<span class="python_operator">...             </span><span class="python_literal">"(addresses.email_address LIKE :x OR addresses.email_address LIKE :y)"</span>
<span class="python_operator">...        </span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...         </span><span class="python_name">from_obj</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_literal">'addresses'</span><span class="python_enclosure">]</span>
<span class="python_operator">...    </span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_72', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_operator">, </span><span class="python_name">x</span><span class="python_operator">=</span><span class="python_literal">'%@aol.com'</span><span class="python_operator">, </span><span class="python_name">y</span><span class="python_operator">=</span><span class="python_literal">'%@msn.com'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_72_div" class="codepop" style="display:none;">SELECT users.fullname || ', ' || addresses.email_address AS title <br/>
FROM users, addresses <br/>
WHERE users.id = addresses.user_id AND users.name BETWEEN 'm' AND 'z' AND (addresses.email_address LIKE ? OR addresses.email_address LIKE ?)<br/>
['%@aol.com', '%@msn.com']</div><pre><span class="python_enclosure">[(</span><span class="python_literal">u'Wendy Williams, wendy@aol.com'</span><span class="python_operator">,</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Going from constructed SQL to text, we lose some capabilities.  We lose the capability for SQLAlchemy to compile our expression to a specific target database; above, our expression won't work with MySQL since it has no <code>||</code> construct.  It also becomes more tedious for SQLAlchemy to be made aware of the datatypes in use; for example, if our bind parameters required UTF-8 encoding before going in, or conversion from a Python <code>datetime</code> into a string (as is required with SQLite), we would have to add extra information to our <code>text()</code> construct.  Similar issues arise on the result set side, where SQLAlchemy also performs type-specific data conversion in some cases; still more information can be added to <code>text()</code> to work around this.  But what we really lose from our statement is the ability to manipulate it, transform it, and analyze it.  These features are critical when using the ORM, which makes heavy usage of relational transformations.  To show off what we mean, we'll first introduce the ALIAS construct and the JOIN construct, just so we have some juicier bits to play with.
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_aliases"></a>
    
    <div class="sectionL2">

    <h3>Using Aliases</h3>
    
    

<p>The alias corresponds to a "renamed" version of a table or arbitrary relation, which occurs anytime you say "SELECT  .. FROM sometable AS someothername".  The <code>AS</code> creates a new name for the table.  Aliases are super important in SQL as they allow you to reference the same table more than once.  Scenarios where you need to do this include when you self-join a table to itself, or more commonly when you need to join from a parent table to a child table multiple times.  For example, we know that our user <code>jack</code> has two email addresses.  How can we locate jack based on the combination of those two addresses?  We need to join twice to it.  Let's construct two distinct aliases for the <code>addresses</code> table and join:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">a1 </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">(</span><span class="python_literal">'a1'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">a2 </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">(</span><span class="python_literal">'a2'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">and_</span><span class="python_enclosure">(</span>
<span class="python_operator">...        </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">a1</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">a2</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">a1</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@msn.com'</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">a2</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@yahoo.com'</span>
<span class="python_operator">...   </span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_73', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_73_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname <br/>
FROM users, addresses AS a1, addresses AS a2 <br/>
WHERE users.id = a1.user_id AND users.id = a2.user_id AND a1.email_address = ? AND a2.email_address = ?<br/>
['jack@msn.com', 'jack@yahoo.com']</div><pre><span class="python_enclosure">[(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Easy enough.  One thing that we're going for with the SQL Expression Language is the melding of programmatic behavior with SQL generation.  Coming up with names like <code>a1</code> and <code>a2</code> is messy; we really didn't need to use those names anywhere, it's just the database that needed them.  Plus, we might write some code that uses alias objects that came from several different places, and it's difficult to ensure that they all have unique names.  So instead, we just let SQLAlchemy make the names for us, using "anonymous" aliases:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">a1 </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">a2 </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">and_</span><span class="python_enclosure">(</span>
<span class="python_operator">...        </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">a1</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">a2</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">a1</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@msn.com'</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">a2</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'jack@yahoo.com'</span>
<span class="python_operator">...   </span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_74', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_74_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname <br/>
FROM users, addresses AS addresses_1, addresses AS addresses_2 <br/>
WHERE users.id = addresses_1.user_id AND users.id = addresses_2.user_id AND addresses_1.email_address = ? AND addresses_2.email_address = ?<br/>
['jack@msn.com', 'jack@yahoo.com']</div><pre><span class="python_enclosure">[(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>One super-huge advantage of anonymous aliases is that not only did we not have to guess up a random name, but we can also be guaranteed that the above SQL string is <strong>deterministically</strong> generated to be the same every time.  This is important for databases such as Oracle which cache compiled "query plans" for their statements, and need to see the same SQL string in order to make use of it.
</p>
<p>Aliases can of course be used for anything which you can SELECT from, including SELECT statements themselves.  We can self-join the <code>users</code> table back to the <code>select()</code> we've created by making an alias of the entire statement.  The <code>correlate(None)</code> directive is to avoid SQLAlchemy's attempt to "correlate" the inner <code>users</code> table with the outer one:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">a1 </span><span class="python_operator">= </span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">correlate</span><span class="python_enclosure">(</span><span class="python_name">None</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">a1</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_75', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_75_div" class="codepop" style="display:none;">SELECT users.name <br/>
FROM users, (SELECT users.id AS id, users.name AS name, users.fullname AS fullname <br/>
FROM users, addresses AS addresses_1, addresses AS addresses_2 <br/>
WHERE users.id = addresses_1.user_id AND users.id = addresses_2.user_id AND addresses_1.email_address = ? AND addresses_2.email_address = ?) AS anon_1 <br/>
WHERE users.id = anon_1.id<br/>
['jack@msn.com', 'jack@yahoo.com']</div><pre><span class="python_enclosure">[(</span><span class="python_literal">u'jack'</span><span class="python_operator">,</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_joins"></a>
    
    <div class="sectionL2">

    <h3>Using Joins</h3>
    
    

<p>We're halfway along to being able to construct any SELECT expression.  The next cornerstone of the SELECT is the JOIN expression.  We've already been doing joins in our examples, by just placing two tables in either the columns clause or the where clause of the <code>select()</code> construct.  But if we want to make a real "JOIN" or "OUTERJOIN" construct, we use the <code>join()</code> and <code>outerjoin()</code> methods, most commonly accessed from the left table in the join:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">users JOIN addresses ON users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">
</span></pre>
    </div>
<p>The alert reader will see more surprises; SQLAlchemy figured out how to JOIN the two tables !  The ON condition of the join, as it's called, was automatically generated based on the <code>ForeignKey</code> object which we placed on the <code>addresses</code> table way at the beginning of this tutorial.  Already the <code>join()</code> construct is looking like a much better way to join tables.
</p>
<p>Of course you can join on whatever expression you want, such as if we want to join on all users who use the same name in their email address as their username:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">+ </span><span class="python_literal">'%'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_name">users JOIN addresses ON addresses</span><span class="python_operator">.</span><span class="python_name">email_address LIKE users</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">|| :</span><span class="python_name">users_name_1</span><span class="python_operator">
</span></pre>
    </div>
<p>When we create a <code>select()</code> construct, SQLAlchemy looks around at the tables we've mentioned and then places them in the FROM clause of the statement.  When we use JOINs however, we know what FROM clause we want, so here we make usage of the <code>from_obj</code> keyword argument:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">from_obj</span><span class="python_operator">=</span><span class="python_enclosure">[</span>
<span class="python_operator">...    </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">+ </span><span class="python_literal">'%'</span><span class="python_enclosure">))</span>
<span class="python_operator">...    </span><span class="python_enclosure">])</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_76', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_76_div" class="codepop" style="display:none;">SELECT users.fullname <br/>
FROM users JOIN addresses ON addresses.email_address LIKE users.name || ?<br/>
['%']</div><pre><span class="python_enclosure">[(</span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">,</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">,</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'Wendy Williams'</span><span class="python_operator">,</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>outerjoin()</code> function just creates <code>LEFT OUTER JOIN</code> constructs.  It's used just like <code>join()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">from_obj</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_enclosure">)])</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">s</span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">
</span><span class="python_name">FROM users LEFT OUTER JOIN addresses ON users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">
</span></pre>
    </div>
<p>That's the output <code>outerjoin()</code> produces, unless, of course, you're stuck in a gig using Oracle prior to version 9, and you've set up your engine (which would be using <code>OracleDialect</code>) to use Oracle-specific SQL:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">databases</span><span class="python_operator">.</span><span class="python_name">oracle </span><span class="python_keyword">import </span><span class="python_name">OracleDialect</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">compile</span><span class="python_enclosure">(</span><span class="python_name">dialect</span><span class="python_operator">=</span><span class="python_name">OracleDialect</span><span class="python_enclosure">(</span><span class="python_name">use_ansi</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">
</span><span class="python_name">FROM users</span><span class="python_operator">, </span><span class="python_name">addresses </span><span class="python_operator">
</span><span class="python_name">WHERE users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">(</span><span class="python_operator">+</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>If you don't know what that SQL means, don't worry !  The secret tribe of Oracle DBAs don't want their black magic being found out ;).
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_transform"></a>
    
    <div class="sectionL2">

    <h3>Intro to Generative Selects and Transformations</h3>
    
    

<p>We've now gained the ability to construct very sophisticated statements.  We can use all kinds of operators, table constructs, text, joins, and aliases.  The point of all of this, as mentioned earlier, is not that it's an "easier" or "better" way to write SQL than just writing a SQL statement yourself; the point is that it's better for writing <em>programmatically generated</em> SQL which can be morphed and adapted as needed in automated scenarios.
</p>
<p>To support this, the <code>select()</code> construct we've been working with supports piecemeal construction, in addition to the "all at once" method we've been doing.  Suppose you're writing a search function, which receives criterion and then must construct a select from it.  To accomplish this, upon each criterion encountered, you apply "generative" criterion to an existing <code>select()</code> construct with new elements, one at a time.  We start with a basic <code>select()</code> constructed with the shortcut method available on the <code>users</code> table:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">query</span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">
</span><span class="python_name">FROM users</span><span class="python_operator">
</span></pre>
    </div>
<p>We encounter search criterion of "name='jack'".  So we apply WHERE criterion stating such:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">where</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Next, we encounter that they'd like the results in descending order by full name.  We apply ORDER BY, using an extra modifier <code>desc</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_operator">.</span><span class="python_name">desc</span><span class="python_enclosure">())</span><span class="python_operator">
</span></pre>
    </div>
<p>We also come across that they'd like only users who have an address at MSN.  A quick way to tack this on is by using an EXISTS clause, which we correlate to the <code>users</code> table in the enclosing SELECT:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">exists</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">where</span><span class="python_enclosure">(</span>
<span class="python_operator">...    </span><span class="python_name">exists</span><span class="python_enclosure">([</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">]</span><span class="python_operator">, </span>
<span class="python_operator">...        </span><span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%@msn.com'</span><span class="python_enclosure">))</span>
<span class="python_operator">...    </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">correlate</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>And finally, the application also wants to see the listing of email addresses at once; so to save queries, we outerjoin the <code>addresses</code> table (using an outer join so that users with no addresses come back as well; since we're programmatic, we might not have kept track that we used an EXISTS clause against the <code>addresses</code> table too...).  Additionally, since the <code>users</code> and <code>addresses</code> table both have a column named <code>id</code>, let's isolate their names from each other in the COLUMNS clause by using labels:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select_from</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">apply_labels</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Let's bake for .0001 seconds and see what rises:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">query</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div class="codepop">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, addresses.id AS addresses_id, addresses.user_id AS addresses_user_id, addresses.email_address AS addresses_email_address <br/>
FROM users LEFT OUTER JOIN addresses ON users.id = addresses.user_id <br/>
WHERE users.name = ? AND (EXISTS (SELECT addresses.id <br/>
FROM addresses <br/>
WHERE addresses.user_id = users.id AND addresses.email_address LIKE ?)) ORDER BY users.fullname DESC<br/>
['jack', '%@msn.com']</div><pre>

<span class="python_enclosure">[(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>So we started small, added one little thing at a time, and at the end we have a huge statement..which actually works.  Now let's do one more thing; the searching function wants to add another <code>email_address</code> criterion on, however it doesn't want to construct an alias of the <code>addresses</code> table; suppose many parts of the application are written to deal specifically with the <code>addresses</code> table, and to change all those functions to support receiving an arbitrary alias of the address would be cumbersome.  We can actually <em>convert</em> the <code>addresses</code> table within the <em>existing</em> statement to be an alias of itself, using <code>replace_selectable()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">a1 </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">replace_selectable</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">, </span><span class="python_name">a1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">query</span><span class="python_operator">
</span></pre><div class="codepop">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, addresses_1.id AS addresses_1_id, addresses_1.user_id AS addresses_1_user_id, addresses_1.email_address AS addresses_1_email_address <br/>
FROM users LEFT OUTER JOIN addresses AS addresses_1 ON users.id = addresses_1.user_id <br/>
WHERE users.name = :users_name_1 AND (EXISTS (SELECT addresses_1.id <br/>
FROM addresses AS addresses_1 <br/>
WHERE addresses_1.user_id = users.id AND addresses_1.email_address LIKE :addresses_email_address_1)) ORDER BY users.fullname DESC</div><pre>

<span class="python_operator"></span></pre>
    </div>
<p>One more thing though, with automatic labeling applied as well as anonymous aliasing, how do we retrieve the columns from the rows for this thing ?  The label for the <code>email_addresses</code> column is now the generated name <code>addresses_1_email_address</code>; and in another statement might be something different !  This is where accessing by result columns by <code>Column</code> object becomes very useful:
</p>

    

    <div class="code">
        <pre> 
<span class="python_literal"><a href="javascript:togglePopbox('popbox_77', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">query</span><span class="python_enclosure">)</span><span class="python_operator">:
...     </span><span class="python_keyword">print </span><span class="python_literal">"Name:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_literal">"; Email Address"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_name">a1</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_enclosure">]</span><span class="python_operator"></span></pre><div id="popbox_77_div" class="codepop" style="display:none;">SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, addresses_1.id AS addresses_1_id, addresses_1.user_id AS addresses_1_user_id, addresses_1.email_address AS addresses_1_email_address <br/>
FROM users LEFT OUTER JOIN addresses AS addresses_1 ON users.id = addresses_1.user_id <br/>
WHERE users.name = ? AND (EXISTS (SELECT addresses_1.id <br/>
FROM addresses AS addresses_1 <br/>
WHERE addresses_1.user_id = users.id AND addresses_1.email_address LIKE ?)) ORDER BY users.fullname DESC<br/>
['jack', '%@msn.com']</div><pre><span class="python_name">Name</span><span class="python_operator">: </span><span class="python_name">jack </span><span class="python_operator">; </span><span class="python_name">Email Address jack</span><span class="python_operator">@</span><span class="python_name">yahoo</span><span class="python_operator">.</span><span class="python_name">com</span><span class="python_operator">
</span><span class="python_name">Name</span><span class="python_operator">: </span><span class="python_name">jack </span><span class="python_operator">; </span><span class="python_name">Email Address jack</span><span class="python_operator">@</span><span class="python_name">msn</span><span class="python_operator">.</span><span class="python_name">com</span><span class="python_operator">
</span></pre>
    </div>
<p>The above example, by its end, got significantly more intense than the typical end-user constructed SQL will usually be.  However when writing higher-level tools such as ORMs, they become more significant.  SQLAlchemy's ORM relies very heavily on techniques like this.
</p>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_everythingelse"></a>
    
    <div class="sectionL2">

    <h3>Everything Else</h3>
    
    

<p>The concepts of creating SQL expressions have been introduced.  What's left are more variants of the same themes.  So now we'll catalog the rest of the important things we'll need to know.
</p>


    
    <A name="sql_everythingelse_bindparams"></a>
    
    <div class="sectionL3">

    <h3>Bind Parameter Objects</h3>
    
    

<p>Throughout all these examples, SQLAlchemy is busy creating bind parameters wherever literal expressions occur.  You can also specify your own bind parameters with your own names, and use the same statement repeatedly.  The database dialect converts to the appropriate named or positional style, as here where it converts to positional for SQLite:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">bindparam</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'username'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_78', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_operator">, </span><span class="python_name">username</span><span class="python_operator">=</span><span class="python_literal">'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_78_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname <br/>
FROM users <br/>
WHERE users.name = ?<br/>
['wendy']</div><pre><span class="python_enclosure">[(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Another important aspect of bind parameters is that they may be assigned a type.  The type of the bind parameter will determine its behavior within expressions and also how the data bound to it is processed before being sent off to the database:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'username'</span><span class="python_operator">, </span><span class="python_name">type_</span><span class="python_operator">=</span><span class="python_name">String</span><span class="python_enclosure">) </span><span class="python_operator">+ </span><span class="python_name">text</span><span class="python_enclosure">(</span><span class="python_literal">"'%'"</span><span class="python_enclosure">)))</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_79', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_operator">, </span><span class="python_name">username</span><span class="python_operator">=</span><span class="python_literal">'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_79_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname <br/>
FROM users <br/>
WHERE users.name LIKE ? || '%'<br/>
['wendy']</div><pre><span class="python_enclosure">[(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_literal">u'Wendy Williams'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<pre><code>
</code></pre><p>Bind parameters of the same name can also be used multiple times, where only a single named value is needed in the execute parameters:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_enclosure">]</span><span class="python_operator">, </span>
<span class="python_operator">...    </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">type_</span><span class="python_operator">=</span><span class="python_name">String</span><span class="python_enclosure">) </span><span class="python_operator">+ </span><span class="python_name">text</span><span class="python_enclosure">(</span><span class="python_literal">"'%'"</span><span class="python_enclosure">)) </span><span class="python_operator">| </span>
<span class="python_operator">...    </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">type_</span><span class="python_operator">=</span><span class="python_name">String</span><span class="python_enclosure">) </span><span class="python_operator">+ </span><span class="python_name">text</span><span class="python_enclosure">(</span><span class="python_literal">"'@%'"</span><span class="python_enclosure">))</span><span class="python_operator">, </span>
<span class="python_operator">...    </span><span class="python_name">from_obj</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_enclosure">)])</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_80', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_80_div" class="codepop" style="display:none;">SELECT users.id, users.name, users.fullname, addresses.id, addresses.user_id, addresses.email_address <br/>
FROM users LEFT OUTER JOIN addresses ON users.id = addresses.user_id <br/>
WHERE users.name LIKE ? || '%' OR addresses.email_address LIKE ? || '@%'<br/>
['jack', 'jack']</div><pre><span class="python_enclosure">[(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_literal">u'Jack Jones'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_everythingelse_functions"></a>
    
    <div class="sectionL3">

    <h3>Functions</h3>
    
    

<p>SQL functions are created using the <code>func</code> keyword, which generates functions using attribute access:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">func</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">now</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">now</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">concat</span><span class="python_enclosure">(</span><span class="python_literal">'x'</span><span class="python_operator">, </span><span class="python_literal">'y'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">concat</span><span class="python_enclosure">(</span><span class="python_operator">:</span><span class="python_name">param_1</span><span class="python_operator">, :</span><span class="python_name">param_2</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Certain functions are marked as "ANSI" functions, which mean they don't get the parenthesis added after them, such as CURRENT_TIMESTAMP:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">current_timestamp</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">CURRENT_TIMESTAMP</span><span class="python_operator">
</span></pre>
    </div>
<p>Functions are most typically used in the columns clause of a select statement, and can also be labeled as well as given a type.  Labeling a function is recommended so that the result can be targeted in a result row based on a string name, and assigning it a type is required when you need result-set processing to occur, such as for Unicode conversion and date conversions.  Below, we use the result function <code>scalar()</code> to just read the first column of the first row and then close the result; the label, even though present, is not important in this case:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span>
<span class="python_operator">...     </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">max</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">, </span><span class="python_name">type_</span><span class="python_operator">=</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'maxemail'</span><span class="python_enclosure">)])</span>
<span class="python_operator">... </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">scalar</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre><div class="codepop">SELECT max(addresses.email_address) AS maxemail <br/>
FROM addresses<br/>
[]</div><pre>

<span class="python_name">www</span><span class="python_operator">@</span><span class="python_name">www</span><span class="python_operator">.</span><span class="python_name">org</span><span class="python_operator">
</span></pre>
    </div>
<p>Databases such as Postgres and Oracle which support functions that return whole result sets can be assembled into selectable units, which can be used in statements.   Such as, a database function <code>calculate()</code> which takes the parameters <code>x</code> and <code>y</code>, and returns three columns which we'd like to name <code>q</code>, <code>z</code> and <code>r</code>, we can construct using "lexical" column objects as well as bind parameters:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">column</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">calculate </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_literal">'q'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_literal">'z'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_literal">'r'</span><span class="python_enclosure">)]</span><span class="python_operator">, </span>
<span class="python_operator">...     </span><span class="python_name">from_obj</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">calculate</span><span class="python_enclosure">(</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'x'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'y'</span><span class="python_enclosure">))])</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">&gt; </span><span class="python_name">calculate</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">z</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">
</span><span class="python_name">FROM users</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_name">SELECT q</span><span class="python_operator">, </span><span class="python_name">z</span><span class="python_operator">, </span><span class="python_name">r </span>
<span class="python_name">FROM calculate</span><span class="python_enclosure">(</span><span class="python_operator">:</span><span class="python_name">x</span><span class="python_operator">, :</span><span class="python_name">y</span><span class="python_enclosure">)) </span><span class="python_operator">
</span><span class="python_name">WHERE users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">&gt; </span><span class="python_name">z</span><span class="python_operator">
</span></pre>
    </div>
<p>If we wanted to use our <code>calculate</code> statement twice with different bind parameters, the <code>unique_params()</code> function will create copies for us, and mark the bind parameters as "unique" so that conflicting names are isolated.  Note we also make two separate aliases of our selectable:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">.</span><span class="python_name">between</span><span class="python_enclosure">(</span>
<span class="python_operator">...    </span><span class="python_name">calculate</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">(</span><span class="python_literal">'c1'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">unique_params</span><span class="python_enclosure">(</span><span class="python_name">x</span><span class="python_operator">=</span><span class="python_number">17</span><span class="python_operator">, </span><span class="python_name">y</span><span class="python_operator">=</span><span class="python_number">45</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">z</span><span class="python_operator">, </span>
<span class="python_operator">...    </span><span class="python_name">calculate</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">(</span><span class="python_literal">'c2'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">unique_params</span><span class="python_enclosure">(</span><span class="python_name">x</span><span class="python_operator">=</span><span class="python_number">5</span><span class="python_operator">, </span><span class="python_name">y</span><span class="python_operator">=</span><span class="python_number">12</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">z</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">s</span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">fullname </span><span class="python_operator">
</span><span class="python_name">FROM users</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_name">SELECT q</span><span class="python_operator">, </span><span class="python_name">z</span><span class="python_operator">, </span><span class="python_name">r </span>
<span class="python_name">FROM calculate</span><span class="python_enclosure">(</span><span class="python_operator">:</span><span class="python_name">x_1</span><span class="python_operator">, :</span><span class="python_name">y_1</span><span class="python_enclosure">)) </span><span class="python_name">AS c1</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_name">SELECT q</span><span class="python_operator">, </span><span class="python_name">z</span><span class="python_operator">, </span><span class="python_name">r </span>
<span class="python_name">FROM calculate</span><span class="python_enclosure">(</span><span class="python_operator">:</span><span class="python_name">x_2</span><span class="python_operator">, :</span><span class="python_name">y_2</span><span class="python_enclosure">)) </span><span class="python_name">AS c2 </span><span class="python_operator">
</span><span class="python_name">WHERE users</span><span class="python_operator">.</span><span class="python_name">id BETWEEN c1</span><span class="python_operator">.</span><span class="python_name">z AND c2</span><span class="python_operator">.</span><span class="python_name">z</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">compile</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">params</span><span class="python_operator">
</span><span class="python_enclosure">{</span><span class="python_literal">'x_2'</span><span class="python_operator">: </span><span class="python_number">5</span><span class="python_operator">, </span><span class="python_literal">'y_2'</span><span class="python_operator">: </span><span class="python_number">12</span><span class="python_operator">, </span><span class="python_literal">'y_1'</span><span class="python_operator">: </span><span class="python_number">45</span><span class="python_operator">, </span><span class="python_literal">'x_1'</span><span class="python_operator">: </span><span class="python_number">17</span><span class="python_enclosure">}</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_everythingelse_unions"></a>
    
    <div class="sectionL3">

    <h3>Unions and Other Set Operations</h3>
    
    

<p>Unions come in two flavors, UNION and UNION ALL, which are available via module level functions:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">union</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">u </span><span class="python_operator">= </span><span class="python_name">union</span><span class="python_enclosure">(</span>
<span class="python_operator">...     </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">==</span><span class="python_literal">'foo@bar.com'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_operator">...    </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%@yahoo.com'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">... </span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_81', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">u</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_81_div" class="codepop" style="display:none;">SELECT addresses.id, addresses.user_id, addresses.email_address <br/>
FROM addresses <br/>
WHERE addresses.email_address = ? UNION SELECT addresses.id, addresses.user_id, addresses.email_address <br/>
FROM addresses <br/>
WHERE addresses.email_address LIKE ? ORDER BY addresses.email_address<br/>
['foo@bar.com', '%@yahoo.com']</div><pre><span class="python_enclosure">[(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Also available, though not supported on all databases, are <code>intersect()</code>, <code>intersect_all()</code>, <code>except_()</code>, and <code>except_all()</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">sql </span><span class="python_keyword">import </span><span class="python_name">except_</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">u </span><span class="python_operator">= </span><span class="python_name">except_</span><span class="python_enclosure">(</span>
<span class="python_operator">...    </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%@%.com'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_operator">...    </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">like</span><span class="python_enclosure">(</span><span class="python_literal">'%@msn.com'</span><span class="python_enclosure">))</span>
<span class="python_operator">... </span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_82', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">u</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_82_div" class="codepop" style="display:none;">SELECT addresses.id, addresses.user_id, addresses.email_address <br/>
FROM addresses <br/>
WHERE addresses.email_address LIKE ? EXCEPT SELECT addresses.id, addresses.user_id, addresses.email_address <br/>
FROM addresses <br/>
WHERE addresses.email_address LIKE ?<br/>
['%@%.com', '%@msn.com']</div><pre><span class="python_enclosure">[(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_number">4</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_literal">u'wendy@aol.com'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_everythingelse_scalar"></a>
    
    <div class="sectionL3">

    <h3>Scalar Selects</h3>
    
    

<p>To embed a SELECT in a column expression, use <code>as_scalar()</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_83', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">select</span><span class="python_enclosure">([</span>
<span class="python_operator">...       </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span>
<span class="python_operator">...       </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">as_scalar</span><span class="python_enclosure">()</span>
<span class="python_operator">...    </span><span class="python_enclosure">]))</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_83_div" class="codepop" style="display:none;">SELECT users.name, (SELECT count(addresses.id) <br/>
FROM addresses <br/>
WHERE users.id = addresses.user_id) AS anon_1 <br/>
FROM users<br/>
[]</div><pre><span class="python_enclosure">[(</span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_number">0</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_number">0</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Alternatively, applying a <code>label()</code> to a select evaluates it as a scalar as well:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_84', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">select</span><span class="python_enclosure">([</span>
<span class="python_operator">...       </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span>
<span class="python_operator">...       </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'address_count'</span><span class="python_enclosure">)</span>
<span class="python_operator">...    </span><span class="python_enclosure">]))</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_84_div" class="codepop" style="display:none;">SELECT users.name, (SELECT count(addresses.id) <br/>
FROM addresses <br/>
WHERE users.id = addresses.user_id) AS address_count <br/>
FROM users<br/>
[]</div><pre><span class="python_enclosure">[(</span><span class="python_literal">u'jack'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'wendy'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'fred'</span><span class="python_operator">, </span><span class="python_number">0</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'mary'</span><span class="python_operator">, </span><span class="python_number">0</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_everythingelse_correlated"></a>
    
    <div class="sectionL3">

    <h3>Correlated Subqueries</h3>
    
    

<p>Notice in the examples on "scalar selects", the FROM clause of each embedded select did not contain the <code>users</code> table in its FROM clause.  This is because SQLAlchemy automatically attempts to correlate embedded FROM objects to that of an enclosing query.  To disable this, or to specify explicit FROM clauses to be correlated, use <code>correlate()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">])</span><span class="python_operator">.</span><span class="python_name">correlate</span><span class="python_enclosure">(</span><span class="python_name">None</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">s</span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">
</span><span class="python_name">FROM users </span><span class="python_operator">
</span><span class="python_name">WHERE users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_enclosure">(</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">id </span>
<span class="python_name">FROM users</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span>
<span class="python_operator">...        </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">correlate</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_enclosure">)</span>
<span class="python_operator">...    </span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">s</span><span class="python_operator">
</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">email_address </span><span class="python_operator">
</span><span class="python_name">FROM users</span><span class="python_operator">, </span><span class="python_name">addresses </span><span class="python_operator">
</span><span class="python_name">WHERE users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_enclosure">(</span><span class="python_name">SELECT users</span><span class="python_operator">.</span><span class="python_name">id </span>
<span class="python_name">FROM users </span>
<span class="python_name">WHERE users</span><span class="python_operator">.</span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_everythingelse_ordering"></a>
    
    <div class="sectionL3">

    <h3>Ordering, Grouping, Limiting, Offset...ing...</h3>
    
    

<p>The <code>select()</code> function can take keyword arguments <code>order_by</code>, <code>group_by</code> (as well as <code>having</code>), <code>limit</code>, and <code>offset</code>.  There's also <code>distinct=True</code>.  These are all also available as generative functions.  <code>order_by()</code> expressions can use the modifiers <code>asc()</code> or <code>desc()</code> to indicate ascending or descending.  <br></br>
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)])</span><span class="python_operator">.\
...     </span><span class="python_name">group_by</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">having</span><span class="python_enclosure">(</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div class="codepop">SELECT addresses.user_id, count(addresses.id) <br/>
FROM addresses GROUP BY addresses.user_id <br/>
HAVING count(addresses.id) &gt; ?<br/>
[1]</div><pre>

<span class="python_enclosure">[(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_enclosure">)]</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">])</span><span class="python_operator">.</span><span class="python_name">distinct</span><span class="python_enclosure">()</span><span class="python_operator">.\
...     </span><span class="python_name">order_by</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_operator">.</span><span class="python_name">desc</span><span class="python_enclosure">()</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div class="codepop">SELECT DISTINCT addresses.email_address, addresses.id <br/>
FROM addresses ORDER BY addresses.email_address DESC, addresses.id<br/>
[]</div><pre>

<span class="python_enclosure">[(</span><span class="python_literal">u'www@www.org'</span><span class="python_operator">, </span><span class="python_number">3</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'wendy@aol.com'</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'jack@yahoo.com'</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_enclosure">(</span><span class="python_literal">u'jack@msn.com'</span><span class="python_operator">, </span><span class="python_number">2</span><span class="python_enclosure">)]</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">addresses</span><span class="python_enclosure">])</span><span class="python_operator">.</span><span class="python_name">offset</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">limit</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">print </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">fetchall</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div class="codepop">SELECT addresses.id, addresses.user_id, addresses.email_address <br/>
FROM addresses <br/>
LIMIT 1 OFFSET 1<br/>
[]</div><pre>

<span class="python_enclosure">[(</span><span class="python_number">2</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">u'jack@msn.com'</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="sql_update"></a>
    
    <div class="sectionL2">

    <h3>Updates</h3>
    
    

<p>Finally, we're back to UPDATE.  Updates work a lot like INSERTS, except there is an additional WHERE clause that can be specified.
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># change 'jack' to 'ed'</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_85', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">update</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator"> </span></pre><div id="popbox_85_div" class="codepop" style="display:none;">UPDATE users SET name=? WHERE users.name = ?<br/>
['ed', 'jack']<br/>
COMMIT</div><pre><span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># use bind parameters</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">u </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">update</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'oldname'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">values</span><span class="python_operator">=</span><span class="python_enclosure">{</span><span class="python_literal">'name'</span><span class="python_operator">:</span><span class="python_name">bindparam</span><span class="python_enclosure">(</span><span class="python_literal">'newname'</span><span class="python_enclosure">)})</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_86', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">u</span><span class="python_operator">, </span><span class="python_name">oldname</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_operator">, </span><span class="python_name">newname</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator"> </span></pre><div id="popbox_86_div" class="codepop" style="display:none;">UPDATE users SET name=? WHERE users.name = ?<br/>
['ed', 'jack']<br/>
COMMIT</div><pre><span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># update a column to an expression</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_87', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">update</span><span class="python_enclosure">(</span><span class="python_name">values</span><span class="python_operator">=</span><span class="python_enclosure">{</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_operator">:</span><span class="python_literal">"Fullname: " </span><span class="python_operator">+ </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">}))</span><span class="python_operator"> </span></pre><div id="popbox_87_div" class="codepop" style="display:none;">UPDATE users SET fullname=(? || users.name)<br/>
['Fullname: ']<br/>
COMMIT</div><pre><span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>


    
    <A name="sql_update_correlated"></a>
    
    <div class="sectionL3">

    <h3>Correlated Updates</h3>
    
    

<p>A correlated update lets you update a table using selection from another table, or the same table:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">email_address</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">limit</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_88', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">update</span><span class="python_enclosure">(</span><span class="python_name">values</span><span class="python_operator">=</span><span class="python_enclosure">{</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">fullname</span><span class="python_operator">:</span><span class="python_name">s</span><span class="python_enclosure">}))</span><span class="python_operator"> </span></pre><div id="popbox_88_div" class="codepop" style="display:none;">UPDATE users SET fullname=(SELECT addresses.email_address <br/>
FROM addresses <br/>
WHERE addresses.user_id = users.id <br/>
LIMIT 1 OFFSET 0)<br/>
[]<br/>
COMMIT</div><pre><span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="sql_delete"></a>
    
    <div class="sectionL2">

    <h3>Deletes</h3>
    
    

<p>Finally, a delete.  Easy enough:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_89', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_operator">.</span><span class="python_name">delete</span><span class="python_enclosure">())</span><span class="python_operator"> </span></pre><div id="popbox_89_div" class="codepop" style="display:none;">DELETE FROM addresses<br/>
[]<br/>
COMMIT</div><pre><span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_90', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">delete</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">&gt; </span><span class="python_literal">'m'</span><span class="python_enclosure">))</span><span class="python_operator"> </span></pre><div id="popbox_90_div" class="codepop" style="display:none;">DELETE FROM users WHERE users.name &gt; ?<br/>
['m']<br/>
COMMIT</div><pre><span class="python_operator">&lt;</span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">base</span><span class="python_operator">.</span><span class="python_name">ResultProxy object at </span><span class="python_number">0x</span><span class="python_operator">...&gt;
</span></pre>
    </div>



            <a href="#sql" class="totoc">back to section top</a>
    </div>



    
    <A name="sql_reference"></a>
    
    <div class="sectionL2">

    <h3>Further Reference</h3>
    
    

<p>The best place to get every possible name you can use in constructed SQL is the <a href="sqlalchemy_sql_expression.html#docstrings_sqlalchemy.sql.expression">Generated Documentation</a>.
</p>
<p>Table Metadata Reference: <a href="#metadata">Database Meta Data</a>
</p>
<p>Engine/Connection/Execution Reference: <a href="#dbengine">Database Engines</a>
</p>
<p>SQL Types: <a href="#types">The Types System</a>
</p>




            <a href="#sql" class="totoc">back to section top</a>
    </div>




    </div>



    
    
    <A name="advdatamapping"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#sql">SQL Expression Language Tutorial</a>

               |   
            Next: <a href="#unitofwork">Using the Session</a>
    </div>

        <h2>Mapper Configuration</h2>
    </div>


        








    
    <A name="advdatamapping"></a>
    
    <div class="sectionL1">

    
    

<p>This section references most major configurational patterns involving the <a href="#docstrings_sqlalchemy.orm_modfunc_mapper">mapper()</a> and <a href="#docstrings_sqlalchemy.orm_modfunc_relation">relation()</a> functions.  It assumes you've worked through the <a href="#datamapping">Object Relational Tutorial</a> and know how to construct and use rudimentary mappers and relations.
</p>


    
    <A name="advdatamapping_mapper"></a>
    
    <div class="sectionL2">

    <h3>Mapper Configuration</h3>
    
    

<p>Full API documentation for the ORM:
</p>
<p><a href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm">module sqlalchemy.orm</a>.
</p>
<p>Options for the <code>mapper()</code> function:
</p>
<p><a href="#docstrings_sqlalchemy.orm_modfunc_mapper">mapper()</a>.
</p>


    
    <A name="advdatamapping_mapper_columns"></a>
    
    <div class="sectionL3">

    <h3>Customizing Column Properties</h3>
    
    

<p>The default behavior of a <code>mapper</code> is to assemble all the columns in the mapped <code>Table</code> into mapped object attributes.  This behavior can be modified in several ways, as well as enhanced by SQL expressions.
</p>
<p>To load only a part of the columns referenced by a table as attributes, use the <code>include_properties</code> and <code>exclude_properties</code> arguments:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">include_properties</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_literal">'user_name'</span><span class="python_enclosure">])</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_operator">, </span><span class="python_name">exclude_properties</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_literal">'street'</span><span class="python_operator">, </span><span class="python_literal">'city'</span><span class="python_operator">, </span><span class="python_literal">'state'</span><span class="python_operator">, </span><span class="python_literal">'zip'</span><span class="python_enclosure">])</span><span class="python_operator">
</span></pre>
    </div>
<p>To change the name of the attribute mapped to a particular column, place the <code>Column</code> object in the <code>properties</code> dictionary with the desired key:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{ </span>
   <span class="python_literal">'id' </span><span class="python_operator">: </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">,</span>
   <span class="python_literal">'name' </span><span class="python_operator">: </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_name</span><span class="python_operator">,</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>To change the names of all attributes using a prefix, use the <code>column_prefix</code> option.  This is useful for classes which wish to add their own <code>property</code> accessors:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">column_prefix</span><span class="python_operator">=</span><span class="python_literal">'_'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The above will place attribute names such as <code>_user_id</code>, <code>_user_name</code>, <code>_password</code> etc. on the mapped <code>User</code> class.
</p>
<p>To place multiple columns which are known to be "synonymous" based on foreign key relationship or join condition into the same mapped attribute, put  them together using a list, as below where we map to a <code>Join</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># join users and addresses
</span><span class="python_name">usersaddresses </span><span class="python_operator">= </span><span class="python_name">sql</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_operator">, \</span>
    <span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id </span><span class="python_operator">== </span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">usersaddresses</span><span class="python_operator">, </span>
   <span class="python_name">properties </span><span class="python_operator">= </span><span class="python_enclosure">{</span>
           <span class="python_literal">'id'</span><span class="python_operator">:</span><span class="python_enclosure">[</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">]</span><span class="python_operator">,</span>
      <span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_deferred"></a>
    
    <div class="sectionL3">

    <h3>Deferred Column Loading</h3>
    
    

<p>This feature allows particular columns of a table to not be loaded by default, instead being loaded later on when first referenced.  It is essentially "column-level lazy loading".   This feature is useful when one wants to avoid loading a large text or binary field into memory when it's not needed.  Individual columns can be lazy loaded by themselves or placed into groups that lazy-load together.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">book_excerpts </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'books'</span><span class="python_operator">, </span><span class="python_name">db</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'book_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'title'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">200</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'summary'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">2000</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'excerpt'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'photo'</span><span class="python_operator">, </span><span class="python_name">Binary</span><span class="python_enclosure">)</span>
  <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">Book</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_comment"># define a mapper that will load each of 'excerpt' and 'photo' in 
# separate, individual-row SELECT statements when each attribute
# is first referenced on the individual object instance
</span><span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Book</span><span class="python_operator">, </span><span class="python_name">book_excerpts</span><span class="python_operator">, </span><span class="python_name">properties </span><span class="python_operator">= </span><span class="python_enclosure">{</span>
  <span class="python_literal">'excerpt' </span><span class="python_operator">: </span><span class="python_name">deferred</span><span class="python_enclosure">(</span><span class="python_name">book_excerpts</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">excerpt</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_literal">'photo' </span><span class="python_operator">: </span><span class="python_name">deferred</span><span class="python_enclosure">(</span><span class="python_name">book_excerpts</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">photo</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Deferred columns can be placed into groups so that they load together:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">book_excerpts </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'books'</span><span class="python_operator">, </span><span class="python_name">db</span><span class="python_operator">, </span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'book_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'title'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">200</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'summary'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">2000</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'excerpt'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'photo1'</span><span class="python_operator">, </span><span class="python_name">Binary</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'photo2'</span><span class="python_operator">, </span><span class="python_name">Binary</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'photo3'</span><span class="python_operator">, </span><span class="python_name">Binary</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">Book</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
  </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_comment"># define a mapper with a 'photos' deferred group.  when one photo is referenced,
# all three photos will be loaded in one SELECT statement.  The 'excerpt' will 
# be loaded separately when it is first referenced.
</span><span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Book</span><span class="python_operator">, </span><span class="python_name">book_excerpts</span><span class="python_operator">, </span><span class="python_name">properties </span><span class="python_operator">= </span><span class="python_enclosure">{</span>
  <span class="python_literal">'excerpt' </span><span class="python_operator">: </span><span class="python_name">deferred</span><span class="python_enclosure">(</span><span class="python_name">book_excerpts</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">excerpt</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_literal">'photo1' </span><span class="python_operator">: </span><span class="python_name">deferred</span><span class="python_enclosure">(</span><span class="python_name">book_excerpts</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">photo1</span><span class="python_operator">, </span><span class="python_name">group</span><span class="python_operator">=</span><span class="python_literal">'photos'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_literal">'photo2' </span><span class="python_operator">: </span><span class="python_name">deferred</span><span class="python_enclosure">(</span><span class="python_name">book_excerpts</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">photo2</span><span class="python_operator">, </span><span class="python_name">group</span><span class="python_operator">=</span><span class="python_literal">'photos'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_literal">'photo3' </span><span class="python_operator">: </span><span class="python_name">deferred</span><span class="python_enclosure">(</span><span class="python_name">book_excerpts</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">photo3</span><span class="python_operator">, </span><span class="python_name">group</span><span class="python_operator">=</span><span class="python_literal">'photos'</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>You can defer or undefer columns at the <code>Query</code> level using the <code>defer</code> and <code>undefer</code> options:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Book</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">defer</span><span class="python_enclosure">(</span><span class="python_literal">'summary'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">undefer</span><span class="python_enclosure">(</span><span class="python_literal">'excerpt'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>And an entire "deferred group", i.e. which uses the <code>group</code> keyword argument to <code>deferred()</code>, can be undeferred using <code>undefer_group()</code>, sending in the group name:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Book</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">undefer_group</span><span class="python_enclosure">(</span><span class="python_literal">'photos'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_expressions"></a>
    
    <div class="sectionL3">

    <h3>SQL Expressions as Mapped Attributes</h3>
    
    

<p>To add a SQL clause composed of local or external columns as a read-only, mapped column attribute, use the <code>column_property()</code> function.  Any scalar-returning <code>ClauseElement</code> may be used, as long as it has a <code>name</code> attribute; usually, you'll want to call <code>label()</code> to give it a specific name:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'fullname' </span><span class="python_operator">: </span><span class="python_name">column_property</span><span class="python_enclosure">(</span>
        <span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">firstname </span><span class="python_operator">+ </span><span class="python_literal">" " </span><span class="python_operator">+ </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">lastname</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'fullname'</span><span class="python_enclosure">)</span>
    <span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Correlated subqueries may be used as well:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'address_count' </span><span class="python_operator">: </span><span class="python_name">column_property</span><span class="python_enclosure">(</span>
            <span class="python_name">select</span><span class="python_enclosure">(</span>
                <span class="python_enclosure">[</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">(</span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">address_id</span><span class="python_enclosure">)]</span><span class="python_operator">, </span>
                <span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span>
            <span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'address_count'</span><span class="python_enclosure">)</span>
        <span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_overriding"></a>
    
    <div class="sectionL3">

    <h3>Overriding Attribute Behavior with Synonyms</h3>
    
    

<p>A common request is the ability to create custom class properties that override the behavior of setting/getting an attribute.  As of 0.4.2, the <code>synonym()</code> construct provides an easy way to do this in conjunction with a normal Python <code>property</code> constructs.  Below, we re-map the <code>email</code> column of our mapped table to a custom attribute setter/getter, mapping the actual column to the property named <code>_email</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MyAddress</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
   </span><span class="python_keyword">def </span><span class="python_name">_set_email</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">email</span><span class="python_enclosure">)</span><span class="python_operator">:
      </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">_email </span><span class="python_operator">= </span><span class="python_name">email</span><span class="python_operator">
   </span><span class="python_keyword">def </span><span class="python_name">_get_email</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
      </span><span class="python_keyword">return </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">_email</span><span class="python_operator">
   </span><span class="python_name">email </span><span class="python_operator">= </span><span class="python_name">property</span><span class="python_enclosure">(</span><span class="python_name">_get_email</span><span class="python_operator">, </span><span class="python_name">_set_email</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">MyAddress</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_operator">, </span><span class="python_name">properties </span><span class="python_operator">= </span><span class="python_enclosure">{</span>
    <span class="python_literal">'email'</span><span class="python_operator">:</span><span class="python_name">synonym</span><span class="python_enclosure">(</span><span class="python_literal">'_email'</span><span class="python_operator">, </span><span class="python_name">map_column</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>email</code> attribute is now usable in the same way as any other mapped attribute, including filter expressions, get/set operations, etc.:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">address </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">MyAddress</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">MyAddress</span><span class="python_operator">.</span><span class="python_name">email </span><span class="python_operator">== </span><span class="python_literal">'some address'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_name">address</span><span class="python_operator">.</span><span class="python_name">email </span><span class="python_operator">= </span><span class="python_literal">'some other address'</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_name">q </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">MyAddress</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">email</span><span class="python_operator">=</span><span class="python_literal">'some other address'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>If the mapped class does not provide a property, the <code>synonym()</code> construct will create a default getter/setter object automatically.
</p>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_composite"></a>
    
    <div class="sectionL3">

    <h3>Composite Column Types</h3>
    
    

<p>Sets of columns can be associated with a single datatype.  The ORM treats the group of columns like a single column which accepts and returns objects using the custom datatype you provide.  In this example, we'll create a table <code>vertices</code> which stores a pair of x/y coordinates, and a custom datatype <code>Point</code> which is a composite type of an x and y column:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">vertices </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'vertices'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'x1'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'y1'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'x2'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'y2'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The requirements for the custom datatype class are that it have a constructor which accepts positional arguments corresponding to its column format, and also provides a method <code>__composite_values__()</code> which returns the state of the object as a list or tuple, in order of its column-based attributes.  It also should supply adequate <code>__eq__()</code> and <code>__ne__()</code> methods which test the equality of two instances:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">Point</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">x</span><span class="python_operator">, </span><span class="python_name">y</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">x </span><span class="python_operator">= </span><span class="python_name">x</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">y </span><span class="python_operator">= </span><span class="python_name">y</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__composite_values__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_enclosure">[</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">x</span><span class="python_operator">, </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">y</span><span class="python_enclosure">]            </span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__eq__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">other</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">other</span><span class="python_operator">.</span><span class="python_name">x </span><span class="python_operator">== </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">x </span><span class="python_keyword">and </span><span class="python_name">other</span><span class="python_operator">.</span><span class="python_name">y </span><span class="python_operator">== </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">y</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__ne__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">other</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return not </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">__eq__</span><span class="python_enclosure">(</span><span class="python_name">other</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Setting up the mapping uses the <code>composite()</code> function:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">Vertex</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Vertex</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'start'</span><span class="python_operator">:</span><span class="python_name">composite</span><span class="python_enclosure">(</span><span class="python_name">Point</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">x1</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">y1</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_literal">'end'</span><span class="python_operator">:</span><span class="python_name">composite</span><span class="python_enclosure">(</span><span class="python_name">Point</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">x2</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">y2</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>We can now use the <code>Vertex</code> instances as well as querying as though the <code>start</code> and <code>end</code> attributes are regular scalar attributes:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">v </span><span class="python_operator">= </span><span class="python_name">Vertex</span><span class="python_enclosure">(</span><span class="python_name">Point</span><span class="python_enclosure">(</span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">Point</span><span class="python_enclosure">(</span><span class="python_number">5</span><span class="python_operator">, </span><span class="python_number">6</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">v</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">v2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Vertex</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Vertex</span><span class="python_operator">.</span><span class="python_name">start </span><span class="python_operator">== </span><span class="python_name">Point</span><span class="python_enclosure">(</span><span class="python_number">3</span><span class="python_operator">, </span><span class="python_number">4</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>The "equals" comparison operation by default produces an AND of all corresponding columns equated to one another.  If you'd like to override this, or define the behavior of other SQL operators for your new type, the <code>composite()</code> function accepts an extension object of type <code>sqlalchemy.orm.PropComparator</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">PropComparator</span><span class="python_operator">
</span><span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_name">sql</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">PointComparator</span><span class="python_enclosure">(</span><span class="python_name">PropComparator</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__gt__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">other</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_literal">"""define the 'greater than' operation"""</span><span class="python_operator">
</span>
        <span class="python_keyword">return </span><span class="python_name">sql</span><span class="python_operator">.</span><span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_operator">*</span><span class="python_enclosure">[</span><span class="python_name">a</span><span class="python_operator">&gt;</span><span class="python_name">b </span><span class="python_keyword">for </span><span class="python_name">a</span><span class="python_operator">, </span><span class="python_name">b </span><span class="python_keyword">in</span>
                          <span class="python_name">zip</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">prop</span><span class="python_operator">.</span><span class="python_name">columns</span><span class="python_operator">,</span>
                              <span class="python_name">other</span><span class="python_operator">.</span><span class="python_name">__composite_values__</span><span class="python_enclosure">())])</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">maper</span><span class="python_enclosure">(</span><span class="python_name">Vertex</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'start'</span><span class="python_operator">:</span><span class="python_name">composite</span><span class="python_enclosure">(</span><span class="python_name">Point</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">x1</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">y1</span><span class="python_operator">, </span><span class="python_name">comparator</span><span class="python_operator">=</span><span class="python_name">PointComparator</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_literal">'end'</span><span class="python_operator">:</span><span class="python_name">composite</span><span class="python_enclosure">(</span><span class="python_name">Point</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">x2</span><span class="python_operator">, </span><span class="python_name">vertices</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">y2</span><span class="python_operator">, </span><span class="python_name">comparator</span><span class="python_operator">=</span><span class="python_name">PointComparator</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_orderby"></a>
    
    <div class="sectionL3">

    <h3>Controlling Ordering</h3>
    
    

<p>By default, mappers will attempt to ORDER BY the "oid" column of a table, or the first primary key column, when selecting rows.  This can be modified in several ways.
</p>
<p>The "order_by" parameter can be sent to a mapper, overriding the per-engine ordering if any.  A value of None means that the mapper should not use any ordering.  A non-None value, which can be a column, an <code>asc</code> or <code>desc</code> clause, or an array of either one, indicates the ORDER BY clause that should be added to all select queries:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># disable all ordering
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">order_by</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># order by a column
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">order_by</span><span class="python_operator">=</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># order by multiple items
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">order_by</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_name</span><span class="python_operator">.</span><span class="python_name">desc</span><span class="python_enclosure">()])</span><span class="python_operator">
</span></pre>
    </div>
<p>"order_by" can also be specified with queries, overriding all other per-engine/per-mapper orderings:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># order by a column
</span><span class="python_name">l </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">user_name</span><span class="python_operator">==</span><span class="python_literal">'fred'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># order by multiple criterion
</span><span class="python_name">l </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">user_name</span><span class="python_operator">==</span><span class="python_literal">'fred'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">([</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">user_name</span><span class="python_operator">.</span><span class="python_name">desc</span><span class="python_enclosure">()])</span><span class="python_operator">
</span></pre>
    </div>
<p>The "order_by" property can also be specified on a <code>relation()</code> which will control the ordering of the collection:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># order address objects by address id
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties </span><span class="python_operator">= </span><span class="python_enclosure">{</span>
    <span class="python_literal">'addresses' </span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">order_by</span><span class="python_operator">=</span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">address_id</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that when using eager loaders with relations, the tables used by the eager load's join are anonymously aliased.  You can only order by these columns if you specify it at the <code>relation()</code> level.  To control ordering at the query level based on a related table, you <code>join()</code> to that relation, then order by it:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">street</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_inheritance"></a>
    
    <div class="sectionL3">

    <h3>Mapping Class Inheritance Hierarchies</h3>
    
    

<p>SQLAlchemy supports three forms of inheritance:  <em>single table inheritance</em>, where several types of classes are stored in one table, <em>concrete table inheritance</em>, where each type of class is stored in its own table, and <em>joined table inheritance</em>, where the parent/child classes are stored in their own tables that are joined together in a select.  Whereas support for single and joined table inheritance is strong, concrete table inheritance is a less common scenario with some particular problems so is not quite as flexible.
</p>
<p>When mappers are configured in an inheritance relationship, SQLAlchemy has the ability to load elements "polymorphically", meaning that a single query can return objects of multiple types.
</p>
<p>For the following sections, assume this class relationship:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">Employee</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__repr__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">__class__</span><span class="python_operator">.</span><span class="python_name">__name__ </span><span class="python_operator">+ </span><span class="python_literal">" " </span><span class="python_operator">+ </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Manager</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">manager_data</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">manager_data </span><span class="python_operator">= </span><span class="python_name">manager_data</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__repr__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">__class__</span><span class="python_operator">.</span><span class="python_name">__name__ </span><span class="python_operator">+ </span><span class="python_literal">" " </span><span class="python_operator">+ </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">+ </span><span class="python_literal">" " </span><span class="python_operator">+  </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">manager_data</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Engineer</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">, </span><span class="python_name">engineer_info</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">engineer_info </span><span class="python_operator">= </span><span class="python_name">engineer_info</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__repr__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">__class__</span><span class="python_operator">.</span><span class="python_name">__name__ </span><span class="python_operator">+ </span><span class="python_literal">" " </span><span class="python_operator">+ </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">+ </span><span class="python_literal">" " </span><span class="python_operator">+  </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">engineer_info</span><span class="python_operator">
</span></pre>
    </div>

    
    <A name="advdatamapping_mapper_inheritance_joined"></a>
    
    <div class="sectionL4">

    <h3>Joined Table Inheritance</h3>
    
    
<p>In joined table inheritance, each class along a particular classes' list of parents is represented by a unique table.  The total set of attributes for a particular instance is represented as a join along all tables in its inheritance path.  Here, we first define a table to represent the <code>Employee</code> class.  This table will contain a primary key column (or columns), and a column for each attribute that's represented by <code>Employee</code>.  In this case it's just <code>name</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">employees </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'type'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">30</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The table also has a column called <code>type</code>.  It is strongly advised in both single- and joined- table inheritance scenarios that the root table contains a column whose sole purpose is that of the <strong>discriminator</strong>; it stores a value which indicates the type of object represented within the row.  The column may be of any desired datatype.  While there are some "tricks" to work around the requirement that there be a discriminator column, they are more complicated to configure when one wishes to load polymorphically.
</p>
<p>Next we define individual tables for each of <code>Engineer</code> and <code>Manager</code>, which each contain columns that represent the attributes unique to the subclass they represent.  Each table also must contain a primary key column (or columns), and in most cases a foreign key reference to the parent table.  It is  standard practice that the same column is used for both of these roles, and that the column is also named the same as that of the parent table.  However this is optional in SQLAlchemy; separate columns may be used for primary key and parent-relation, the column may be named differently than that of the parent, and even a custom join condition can be specified between parent and child tables instead of using a foreign key.  In joined table inheritance, the primary key of an instance is always represented by the primary key of the base table only (new in SQLAlchemy 0.4).
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engineers </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'engineers'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'employees.employee_id'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'engineer_info'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">managers </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'managers'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'employees.employee_id'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'manager_data'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>We then configure mappers as usual, except we use some additional arguments to indicate the inheritance relationship, the polymorphic discriminator column, and the <strong>polymorphic identity</strong> of each class; this is the value that will be stored in the polymorphic discriminator column.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">employees</span><span class="python_operator">, </span><span class="python_name">polymorphic_on</span><span class="python_operator">=</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'employee'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">engineers</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'engineer'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Manager</span><span class="python_operator">, </span><span class="python_name">managers</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'manager'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>And that's it.  Querying against <code>Employee</code> will return a combination of <code>Employee</code>, <code>Engineer</code> and <code>Manager</code> objects.
</p>

    
    <A name="advdatamapping_mapper_inheritance_joined_querying"></a>
    
    <div class="sectionL4">

    <h3>Polymorphic Querying Strategies</h3>
    
    
<p>The <code>Query</code> object includes some helper functionality when dealing with joined-table inheritance mappings.  These are the <code>with_polymorphic()</code> and <code>of_type()</code> methods, both of which are introduced in version 0.4.4.
</p>
<p>The <code>with_polymorphic()</code> method affects the specific subclass tables which the Query selects from.  Normally, a query such as this:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">==</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Selects only from the <code>employees</code> table.  The criterion we use in <code>filter()</code> and other methods will generate WHERE criterion against this table.  What if we wanted to load <code>Employee</code> objects but also wanted to use criterion against <code>Engineer</code> ?  We could just query against the <code>Engineer</code> class instead.  But, if we were using criterion which filters among more than one subclass (subclasses which do not inherit directly from one to the other), we'd like to select from an outer join of all those tables.  The <code>with_polymorphic()</code> method can tell <code>Query</code> which joined-table subclasses we want to select for:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">with_polymorphic</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">.</span><span class="python_name">engineer_info</span><span class="python_operator">==</span><span class="python_literal">'some info'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Even without criterion, the <code>with_polymorphic()</code> method has the added advantage that instances are loaded from all of their tables in one result set.  Such as, to optimize the loading of all <code>Employee</code> objects, <code>with_polymorphic()</code> accepts <code>'*'</code> as a wildcard indicating that all subclass tables should be joined:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">with_polymorphic</span><span class="python_enclosure">(</span><span class="python_literal">'*'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p><code>with_polymorphic()</code> is an effective query-level alternative to the existing <code>select_table</code> option available on <code>mapper()</code>.
</p>
<p>Next is a way to join along <code>relation</code> paths while narrowing the criterion to specific subclasses.  Suppose the <code>employees</code> table represents a collection of employees which are associated with a <code>Company</code> object.  We'll add a <code>company_id</code> column to the <code>employees</code> table and a new table <code>companies</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">companies </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'companies'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'company_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span>
   <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">employees </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'type'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">30</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'company_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'companies.company_id'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">Company</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_operator">, </span><span class="python_name">companies</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'employees'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>If we wanted to join from <code>Company</code> to not just <code>Employee</code> but specifically <code>Engineers</code>, using the <code>join()</code> method or <code>any()</code> or <code>has()</code> operators will by default create a join from <code>companies</code> to <code>employees</code>, without including <code>engineers</code> or <code>managers</code> in the mix.  If we wish to have criterion which is specifically against the <code>Engineer</code> class, we can tell those methods to join or subquery against the full set of tables representing the subclass using the <code>of_type()</code> opertator:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_operator">.</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">of_type</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">.</span><span class="python_name">engineer_info</span><span class="python_operator">==</span><span class="python_literal">'someinfo'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>A longhand notation, introduced in 0.4.3, is also available, which involves spelling out the full target selectable within a 2-tuple:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">((</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">engineers</span><span class="python_enclosure">)))</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">.</span><span class="python_name">engineer_info</span><span class="python_operator">==</span><span class="python_literal">'someinfo'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The second notation allows more flexibility, such as joining to any group of subclass tables:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">((</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">engineers</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">managers</span><span class="python_enclosure">)))</span><span class="python_operator">.\
    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">or_</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">.</span><span class="python_name">engineer_info</span><span class="python_operator">==</span><span class="python_literal">'someinfo'</span><span class="python_operator">, </span><span class="python_name">Manager</span><span class="python_operator">.</span><span class="python_name">manager_data</span><span class="python_operator">==</span><span class="python_literal">'somedata'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>any()</code> and <code>has()</code> operators also can be used with <code>of_type()</code> when the embedded criterion is in terms of a subclass:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_operator">.</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">of_type</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">any</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">.</span><span class="python_name">engineer_info</span><span class="python_operator">==</span><span class="python_literal">'someinfo'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that the <code>any()</code> and <code>has()</code> are both shorthand for a correlated EXISTS query.  To build one by hand looks like:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span>
    <span class="python_name">exists</span><span class="python_enclosure">([</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">, </span>
        <span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">.</span><span class="python_name">engineer_info</span><span class="python_operator">==</span><span class="python_literal">'someinfo'</span><span class="python_operator">, </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">company_id</span><span class="python_operator">==</span><span class="python_name">companies</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">company_id</span><span class="python_enclosure">)</span><span class="python_operator">, </span>
        <span class="python_name">from_obj</span><span class="python_operator">=</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">engineers</span><span class="python_enclosure">)</span>
    <span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The EXISTS subquery above selects from the join of <code>employees</code> to <code>engineers</code>, and also specifies criterion which correlates the EXISTS subselect back to the parent <code>companies</code> table.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_inheritance_joined_optimizing"></a>
    
    <div class="sectionL4">

    <h3>Optimizing Joined Table Loads</h3>
    
    
<p>When loading fresh from the database, the joined-table setup above will query from the parent table first, then for each row will issue a second query to the child table.  For example, for a load of five rows with <code>Employee</code> id 3, <code>Manager</code> ids 1 and 5 and <code>Engineer</code> ids 2 and 4, will produce queries along the lines of this example:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre><div class="codepop">SELECT employees.employee_id AS employees_employee_id, employees.name AS employees_name, employees.type AS employees_type <br/>
FROM employees ORDER BY employees.oid<br/>
[]<br/>
SELECT managers.employee_id AS managers_employee_id, managers.manager_data AS managers_manager_data <br/>
FROM managers <br/>
WHERE ? = managers.employee_id<br/>
[5]<br/>
SELECT engineers.employee_id AS engineers_employee_id, engineers.engineer_info AS engineers_engineer_info <br/>
FROM engineers <br/>
WHERE ? = engineers.employee_id<br/>
[2]<br/>
SELECT engineers.employee_id AS engineers_employee_id, engineers.engineer_info AS engineers_engineer_info <br/>
FROM engineers <br/>
WHERE ? = engineers.employee_id<br/>
[4]<br/>
SELECT managers.employee_id AS managers_employee_id, managers.manager_data AS managers_manager_data <br/>
FROM managers <br/>
WHERE ? = managers.employee_id<br/>
[1]</div><pre>

<span class="python_operator"></span></pre>
    </div>
<p>The above query works well for a <code>get()</code> operation, since it limits the queries to only the tables directly involved in fetching a single instance.  For instances which are already present in the session, the secondary table load is not needed.  However, the above loading style is not efficient for loading large groups of objects, as it incurs separate queries for each parent row.
</p>
<p>One way to reduce the number of "secondary" loads of child rows is to "defer" them, using <code>polymorphic_fetch='deferred'</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">employees</span><span class="python_operator">, </span><span class="python_name">polymorphic_on</span><span class="python_operator">=</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">, \</span>
    <span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'employee'</span><span class="python_operator">, </span><span class="python_name">polymorphic_fetch</span><span class="python_operator">=</span><span class="python_literal">'deferred'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">engineers</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'engineer'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Manager</span><span class="python_operator">, </span><span class="python_name">managers</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'manager'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The above configuration queries in the same manner as earlier, except the load of each "secondary" table occurs only when attributes referencing those columns are first referenced on the loaded instance.  This style of loading is very efficient for cases where large selects of items occur, but a detailed "drill down" of extra inherited properties is less common.
</p>
<p>More commonly, an all-at-once load may be achieved by constructing a query which combines all three tables together.  The easiest way to do this as of version 0.4.4 is to use the <code>with_polymorphic()</code> query method which will automatically join in the classes desired:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">with_polymorphic</span><span class="python_enclosure">([</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">Manager</span><span class="python_enclosure">])</span><span class="python_operator">
</span></pre>
    </div>
<p>Which produces a query like the following:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre><div class="codepop">SELECT employees.employee_id AS employees_employee_id, engineers.employee_id AS engineers_employee_id, managers.employee_id AS managers_employee_id, employees.name AS employees_name, employees.type AS employees_type, engineers.engineer_info AS engineers_engineer_info, managers.manager_data AS managers_manager_data <br/>
FROM employees LEFT OUTER JOIN engineers ON employees.employee_id = engineers.employee_id LEFT OUTER JOIN managers ON employees.employee_id = managers.employee_id ORDER BY employees.oid<br/>
[]</div><pre>

<span class="python_operator"></span></pre>
    </div>
<p><code>with_polymorphic()</code> accepts a single class or mapper, a list of classes/mappers, or the string <code>'*'</code> to indicate all subclasses.  It also accepts a second argument <code>selectable</code> which replaces the automatic join creation and instead selects directly from the selectable given.  This can allow polymorphic loads from a variety of inheritance schemes including concrete tables, if the appropriate unions are constructed.
</p>
<p>Similar behavior as provided by <code>with_polymorphic()</code> can be configured at the mapper level so that any user-defined query is used by default in order to load instances.  The <code>select_table</code> argument references an arbitrary selectable which the mapper will use for load operations (it has no impact on save operations).  Any selectable can be used for this, such as a UNION of tables.  For joined table inheritance, the easiest method is to use OUTER JOIN:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">join </span><span class="python_operator">= </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">engineers</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">managers</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">employees</span><span class="python_operator">, </span><span class="python_name">polymorphic_on</span><span class="python_operator">=</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">, \</span>
    <span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'employee'</span><span class="python_operator">, </span><span class="python_name">select_table</span><span class="python_operator">=</span><span class="python_name">join</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">engineers</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'engineer'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Manager</span><span class="python_operator">, </span><span class="python_name">managers</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'manager'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The above mapping will produce a query similar to that of <code>with_polymorphic('*')</code> for every query of <code>Employee</code> objects.
</p>
<p>When <code>select_table</code> is used, <code>with_polymorphic()</code> still overrides its usage at the query level.  For example, if <code>select_table</code> were configured to load from a join of multiple tables, using <code>with_polymorphic(Employee)</code> will limit the list of tables selected from to just the base table (as always, tables which don't get loaded in the first pass will be loaded on an as-needed basis).
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_mapper_inheritance_single"></a>
    
    <div class="sectionL4">

    <h3>Single Table Inheritance</h3>
    
    
<p>Single table inheritance is where the attributes of the base class as well as all subclasses are represented within a single table.  A column is present in the table for every attribute mapped to the base class and all subclasses; the columns which correspond to a single subclass are nullable.  This configuration looks much like joined-table inheritance except there's only one table.  In this case, a <code>type</code> column is required, as there would be no other way to discriminate between classes.  The table is specified in the base mapper only; for the inheriting classes, leave their <code>table</code> parameter blank:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">employees_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'manager_data'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'engineer_info'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'type'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">20</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">employee_mapper </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">employees_table</span><span class="python_operator">, \</span>
    <span class="python_name">polymorphic_on</span><span class="python_operator">=</span><span class="python_name">employees_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'employee'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">manager_mapper </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Manager</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">employee_mapper</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'manager'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">engineer_mapper </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">employee_mapper</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'engineer'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that the mappers for the derived classes Manager and Engineer omit the specification of their associated table, as it is inherited from the employee_mapper. Omitting the table specification for derived mappers in single-table inheritance is required.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_inheritance_concrete"></a>
    
    <div class="sectionL4">

    <h3>Concrete Table Inheritance</h3>
    
    
<p>This form of inheritance maps each class to a distinct table, as below:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">employees_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">managers_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'managers'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'manager_data'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">engineers_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'engineers'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'engineer_info'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Notice in this case there is no <code>type</code> column.  If polymorphic loading is not required, there's no advantage to using <code>inherits</code> here; you just define a separate mapper for each class.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">employees_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Manager</span><span class="python_operator">, </span><span class="python_name">managers_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">engineers_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>To load polymorphically, the <code>select_table</code> argument is currently required.  In this case we must construct a UNION of all three tables.  SQLAlchemy includes a helper function to create these called <code>polymorphic_union</code>, which will map all the different columns into a structure of selects with the same numbers and names of columns, and also generate a virtual <code>type</code> column for each subselect:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">pjoin </span><span class="python_operator">= </span><span class="python_name">polymorphic_union</span><span class="python_enclosure">({</span>
    <span class="python_literal">'employee'</span><span class="python_operator">:</span><span class="python_name">employees_table</span><span class="python_operator">,</span>
    <span class="python_literal">'manager'</span><span class="python_operator">:</span><span class="python_name">managers_table</span><span class="python_operator">,</span>
    <span class="python_literal">'engineer'</span><span class="python_operator">:</span><span class="python_name">engineers_table</span>
<span class="python_enclosure">}</span><span class="python_operator">, </span><span class="python_literal">'type'</span><span class="python_operator">, </span><span class="python_literal">'pjoin'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">employee_mapper </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">employees_table</span><span class="python_operator">, </span><span class="python_name">select_table</span><span class="python_operator">=</span><span class="python_name">pjoin</span><span class="python_operator">, \</span>
    <span class="python_name">polymorphic_on</span><span class="python_operator">=</span><span class="python_name">pjoin</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'employee'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">manager_mapper </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Manager</span><span class="python_operator">, </span><span class="python_name">managers_table</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">employee_mapper</span><span class="python_operator">, \</span>
    <span class="python_name">concrete</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'manager'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">engineer_mapper </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">engineers_table</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">employee_mapper</span><span class="python_operator">, \</span>
    <span class="python_name">concrete</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'engineer'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Upon select, the polymorphic union produces a query like this:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre><div class="codepop">SELECT pjoin.type AS pjoin_type, pjoin.manager_data AS pjoin_manager_data, pjoin.employee_id AS pjoin_employee_id, <br/>
pjoin.name AS pjoin_name, pjoin.engineer_info AS pjoin_engineer_info <br/>
FROM (<br/>
    SELECT employees.employee_id AS employee_id, CAST(NULL AS VARCHAR(50)) AS manager_data, employees.name AS name, <br/>
    CAST(NULL AS VARCHAR(50)) AS engineer_info, 'employee' AS type <br/>
    FROM employees <br/>
UNION ALL <br/>
    SELECT managers.employee_id AS employee_id, managers.manager_data AS manager_data, managers.name AS name, <br/>
    CAST(NULL AS VARCHAR(50)) AS engineer_info, 'manager' AS type <br/>
    FROM managers <br/>
UNION ALL <br/>
    SELECT engineers.employee_id AS employee_id, CAST(NULL AS VARCHAR(50)) AS manager_data, engineers.name AS name, <br/>
    engineers.engineer_info AS engineer_info, 'engineer' AS type <br/>
    FROM engineers<br/>
) AS pjoin ORDER BY pjoin.oid<br/>
[]</div><pre>

<span class="python_operator"></span></pre>
    </div>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_inheritance_relations"></a>
    
    <div class="sectionL4">

    <h3>Using Relations with Inheritance</h3>
    
    
<p>Both joined-table and single table inheritance scenarios produce mappings which are usable in relation() functions; that is, it's possible to map a parent object to a child object which is polymorphic.  Similarly, inheriting mappers can have <code>relation()</code>s of their own at any level, which are inherited to each child class.  The only requirement for relations is that there is a table relationship between parent and child.  An example is the following modification to the joined table inheritance example, which sets a bi-directional relationship between <code>Employee</code> and <code>Company</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">employees_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'company_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'companies.company_id'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">companies </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'companies'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'company_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">)))</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">Company</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_operator">, </span><span class="python_name">companies</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
   <span class="python_literal">'employees'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'company'</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>SQLAlchemy has a lot of experience in this area; the optimized "outer join" approach can be used freely for parent and child relationships, eager loads are fully useable, query aliasing and other tricks are fully supported as well.
</p>
<p>In a concrete inheritance scenario, mapping <code>relation()</code>s is more difficult since the distinct classes do not share a table.  In this case, you <em>can</em> establish a relationship from parent to child if a join condition can be constructed from parent to child, if each child table contains a foreign key to the parent:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">companies </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'companies'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">)))</span><span class="python_operator">
</span>
<span class="python_name">employees_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'company_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'companies.id'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">managers_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'managers'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'manager_data'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'company_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'companies.id'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">engineers_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'engineers'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'engineer_info'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'company_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'companies.id'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_operator">, </span><span class="python_name">employees_table</span><span class="python_operator">, </span><span class="python_name">select_table</span><span class="python_operator">=</span><span class="python_name">pjoin</span><span class="python_operator">, </span><span class="python_name">polymorphic_on</span><span class="python_operator">=</span><span class="python_name">pjoin</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'employee'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Manager</span><span class="python_operator">, </span><span class="python_name">managers_table</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">employee_mapper</span><span class="python_operator">, </span><span class="python_name">concrete</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'manager'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Engineer</span><span class="python_operator">, </span><span class="python_name">engineers_table</span><span class="python_operator">, </span><span class="python_name">inherits</span><span class="python_operator">=</span><span class="python_name">employee_mapper</span><span class="python_operator">, </span><span class="python_name">concrete</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">polymorphic_identity</span><span class="python_operator">=</span><span class="python_literal">'engineer'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_operator">, </span><span class="python_name">companies</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'employees'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Employee</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Let's crank it up and try loading with an eager load:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Company</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre><div class="codepop">SELECT anon_1.type AS anon_1_type, anon_1.manager_data AS anon_1_manager_data, anon_1.engineer_info AS anon_1_engineer_info, <br/>
anon_1.employee_id AS anon_1_employee_id, anon_1.name AS anon_1_name, anon_1.company_id AS anon_1_company_id, <br/>
companies.id AS companies_id, companies.name AS companies_name <br/>
FROM companies LEFT OUTER JOIN (SELECT CAST(NULL AS VARCHAR(50)) AS engineer_info, employees.employee_id AS employee_id, <br/>
CAST(NULL AS VARCHAR(50)) AS manager_data, employees.name AS name, employees.company_id AS company_id, 'employee' AS type <br/>
FROM employees UNION ALL SELECT CAST(NULL AS VARCHAR(50)) AS engineer_info, managers.employee_id AS employee_id, <br/>
managers.manager_data AS manager_data, managers.name AS name, managers.company_id AS company_id, 'manager' AS type <br/>
FROM managers UNION ALL SELECT engineers.engineer_info AS engineer_info, engineers.employee_id AS employee_id, <br/>
CAST(NULL AS VARCHAR(50)) AS manager_data, engineers.name AS name, engineers.company_id AS company_id, 'engineer' AS type <br/>
FROM engineers) AS anon_1 ON companies.id = anon_1.company_id ORDER BY companies.oid, anon_1.oid<br/>
[]</div><pre>

<span class="python_operator"></span></pre>
    </div>
<p>The big limitation with concrete table inheritance is that relation()s placed on each concrete mapper do <strong>not</strong> propagate to child mappers.  If you want to have the same relation()s set up on all concrete mappers, they must be configured manually on each.
</p>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_mapper_joins"></a>
    
    <div class="sectionL3">

    <h3>Mapping a Class against Multiple Tables</h3>
    
    

<p>Mappers can be constructed against arbitrary relational units (called <code>Selectables</code>) as well as plain <code>Tables</code>.  For example, The <code>join</code> keyword from the SQL package creates a neat selectable unit comprised of multiple tables, complete with its own composite primary key, which can be passed in to a mapper as the table.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># a class
</span><span class="python_keyword">class </span><span class="python_name">AddressUser</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_comment"># define a Join
</span><span class="python_operator"></span><span class="python_name">j </span><span class="python_operator">= </span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># map to it - the identity of an AddressUser object will be 
# based on (user_id, address_id) since those are the primary keys involved
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">AddressUser</span><span class="python_operator">, </span><span class="python_name">j</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'user_id'</span><span class="python_operator">:</span><span class="python_enclosure">[</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">]</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>A second example:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># many-to-many join on an association table
</span><span class="python_name">j </span><span class="python_operator">= </span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">userkeywords</span><span class="python_operator">, </span>
        <span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">userkeywords</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">keywords</span><span class="python_operator">, </span>
           <span class="python_name">userkeywords</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">keyword_id</span><span class="python_operator">==</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">keyword_id</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># a class 
</span><span class="python_keyword">class </span><span class="python_name">KeywordUser</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_comment"># map to it - the identity of a KeywordUser object will be
# (user_id, keyword_id) since those are the primary keys involved
</span><span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">KeywordUser</span><span class="python_operator">, </span><span class="python_name">j</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'user_id'</span><span class="python_operator">:</span><span class="python_enclosure">[</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span><span class="python_name">userkeywords</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">]</span><span class="python_operator">,</span>
    <span class="python_literal">'keyword_id'</span><span class="python_operator">:</span><span class="python_enclosure">[</span><span class="python_name">userkeywords</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">keyword_id</span><span class="python_operator">, </span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">keyword_id</span><span class="python_enclosure">]</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>In both examples above, "composite" columns were added as properties to the mappers; these are aggregations of multiple columns into one mapper property, which instructs the mapper to keep both of those columns set at the same value.
</p>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_selects"></a>
    
    <div class="sectionL3">

    <h3>Mapping a Class against Arbitrary Selects</h3>
    
    

<p>Similar to mapping against a join, a plain select() object can be used with a mapper as well.  Below, an example select which contains two aggregate functions and a group_by is mapped to a class:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">customers</span><span class="python_operator">, </span>
            <span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">(</span><span class="python_name">orders</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'order_count'</span><span class="python_enclosure">)</span><span class="python_operator">, </span>
            <span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">max</span><span class="python_enclosure">(</span><span class="python_name">orders</span><span class="python_operator">.</span><span class="python_name">price</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">label</span><span class="python_enclosure">(</span><span class="python_literal">'highest_order'</span><span class="python_enclosure">)]</span><span class="python_operator">,</span>
            <span class="python_name">customers</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">customer_id</span><span class="python_operator">==</span><span class="python_name">orders</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">customer_id</span><span class="python_operator">,</span>
            <span class="python_name">group_by</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">c </span><span class="python_keyword">for </span><span class="python_name">c </span><span class="python_keyword">in </span><span class="python_name">customers</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_enclosure">]</span>
            <span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">(</span><span class="python_literal">'somealias'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">Customer</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Customer</span><span class="python_operator">, </span><span class="python_name">s</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, the "customers" table is joined against the "orders" table to produce a full row for each customer row, the total count of related rows in the "orders" table, and the highest price in the "orders" table, grouped against the full set of columns in the "customers" table.  That query is then mapped against the Customer class.  New instances of Customer will contain attributes for each column in the "customers" table as well as an "order_count" and "highest_order" attribute.  Updates to the Customer object will only be reflected in the "customers" table and not the "orders" table.  This is because the primary key columns of the "orders" table are not represented in this mapper and therefore the table is not affected by save or delete operations.
</p>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_multiple"></a>
    
    <div class="sectionL3">

    <h3>Multiple Mappers for One Class</h3>
    
    

<p>The first mapper created for a certain class is known as that class's "primary mapper."  Other mappers can be created as well, these come in two varieties.
</p>
<ul>
 <li><p><strong>secondary mapper</strong>
   this is a mapper that must be constructed with the keyword argument <code>non_primary=True</code>, and represents a load-only mapper.  Objects that are loaded with a secondary mapper will have their save operation processed by the primary mapper.  It is also invalid to add new <code>relation()</code>s to a non-primary mapper. To use this mapper with the Session, specify it to the <code>query</code> method:
</p>
<p>example:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># primary mapper
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># make a secondary mapper to load User against a join
</span><span class="python_name">othermapper </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_name">someothertable</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">non_primary</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># select
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">othermapper</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The "non primary mapper" is a rarely needed feature of SQLAlchemy; in most cases, the <code>Query</code> object can produce any kind of query that's desired.  It's recommended that a straight <code>Query</code> be used in place of a non-primary mapper unless the mapper approach is absolutely needed.  Current use cases for the "non primary mapper" are when you want to map the class to a particular select statement or view to which additional query criterion can be added, and for when the particular mapped select statement or view is to be placed in a <code>relation()</code> of a parent mapper.
</p>

 </li>

 <li><p><strong>entity name mapper</strong>
   this is a mapper that is a fully functioning primary mapper for a class, which is distinguished from the regular primary mapper by an <code>entity_name</code> parameter.  Instances loaded with this mapper will be totally managed by this new mapper and have no connection to the original one.  Most methods on <code>Session</code> include an optional <code>entity_name</code> parameter in order to specify this condition.
</p>
<p>example:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># primary mapper
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># make an entity name mapper that stores User objects in another table
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">alternate_users_table</span><span class="python_operator">, </span><span class="python_name">entity_name</span><span class="python_operator">=</span><span class="python_literal">'alt'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># make two User objects
</span><span class="python_name">user1 </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">user2 </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># save one in in the "users" table
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">user1</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># save the other in the "alternate_users_table"
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">user2</span><span class="python_operator">, </span><span class="python_name">entity_name</span><span class="python_operator">=</span><span class="python_literal">'alt'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># select from the alternate mapper
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">entity_name</span><span class="python_operator">=</span><span class="python_literal">'alt'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Use the "entity name" mapper when different instances of the same class are persisted in completely different tables.  The "entity name" approach can also perform limited levels of horizontal partitioning as well.   A more comprehensive approach to horizontal partitioning is provided by the Sharding API.
</p>

 </li>
</ul>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_mapper_extending"></a>
    
    <div class="sectionL3">

    <h3>Extending Mapper</h3>
    
    

<p>Mappers can have functionality augmented or replaced at many points in its execution via the usage of the MapperExtension class.  This class is just a series of "hooks" where various functionality takes place.  An application can make its own MapperExtension objects, overriding only the methods it needs.  Methods that are not overridden return the special value <code>sqlalchemy.orm.EXT_CONTINUE</code> to allow processing to continue to the next MapperExtension or simply proceed normally if there are no more extensions.
</p>
<p>API documentation for MapperExtension: <a href="sqlalchemy_orm.html#docstrings_sqlalchemy.orm_MapperExtension">class MapperExtension(object)</a>
</p>
<p>To use MapperExtension, make your own subclass of it and just send it off to a mapper:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">m </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">extension</span><span class="python_operator">=</span><span class="python_name">MyExtension</span><span class="python_enclosure">())</span><span class="python_operator">
</span></pre>
    </div>
<p>Multiple extensions will be chained together and processed in order; they are specified as a list:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">m </span><span class="python_operator">= </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">extension</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">ext1</span><span class="python_operator">, </span><span class="python_name">ext2</span><span class="python_operator">, </span><span class="python_name">ext3</span><span class="python_enclosure">])</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_relation"></a>
    
    <div class="sectionL2">

    <h3>Relation Configuration</h3>
    
    

<p>The full list of options for the <code>relation()</code> function:
</p>
<p><a href="#docstrings_sqlalchemy.orm_modfunc_relation">relation()</a>
</p>


    
    <A name="advdatamapping_relation_patterns"></a>
    
    <div class="sectionL3">

    <h3>Basic Relational Patterns</h3>
    
    

<p>A quick walkthrough of the basic relational patterns.
</p>

    
    <A name="advdatamapping_relation_patterns_onetomany"></a>
    
    <div class="sectionL4">

    <h3>One To Many</h3>
    
    
<p>A one to many relationship places a foreign key in the child table referencing the parent.   SQLAlchemy creates the relationship as a collection on the parent object containing instances of the child object.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">parent_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'parent'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">child_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'child'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'parent_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'parent.id'</span><span class="python_enclosure">)))</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">Parent</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Child</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">parent_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">child_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>To establish a bi-directional relationship in one-to-many, where the "reverse" side is a many to one, specify the <code>backref</code> option:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">parent_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'parent'</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">child_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p><code>Child</code> will get a <code>parent</code> attribute with many-to-one semantics.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_patterns_manytoone"></a>
    
    <div class="sectionL4">

    <h3>Many To One</h3>
    
    
<p>Many to one places a foreign key in the parent table referencing the child.  The mapping setup is identical to one-to-many, however SQLAlchemy creates the relationship as a scalar attribute on the parent object referencing a single instance of the child object.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">parent_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'parent'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'child_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'child.id'</span><span class="python_enclosure">)))</span><span class="python_operator">
</span>
<span class="python_name">child_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'child'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">Parent</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Child</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">parent_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'child'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">child_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Backref behavior is available here as well, where <code>backref=&quot;parents&quot;</code> will place a one-to-many collection on the <code>Child</code> class.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_patterns_onetoone"></a>
    
    <div class="sectionL4">

    <h3>One To One</h3>
    
    
<p>One To One is essentially a bi-directional relationship with a scalar attribute on both sides.  To achieve this, the <code>uselist=False</code> flag indicates the placement of a scalar attribute instead of a collection on the "many" side of the relationship.  To convert one-to-many into one-to-one:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">parent_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'child'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">uselist</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'parent'</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Or to turn many-to-one into one-to-one:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">parent_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'child'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_name">backref</span><span class="python_enclosure">(</span><span class="python_literal">'parent'</span><span class="python_operator">, </span><span class="python_name">uselist</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">))</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_patterns_manytomany"></a>
    
    <div class="sectionL4">

    <h3>Many To Many</h3>
    
    
<p>Many to Many adds an association table between two classes.  The association table is indicated by the <code>secondary</code> argument to <code>relation()</code>.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">left_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'left'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">right_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'right'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">association_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'association'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'left_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'left.id'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'right_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'right.id'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">left_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">secondary</span><span class="python_operator">=</span><span class="python_name">association_table</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">right_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>For a bi-directional relationship, both sides of the relation contain a collection by default, which can be modified on either side via the <code>uselist</code> flag to be scalar.  The <code>backref</code> keyword will automatically use the same <code>secondary</code> argument for the reverse relation:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">left_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">secondary</span><span class="python_operator">=</span><span class="python_name">association_table</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'parents'</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_patterns_association"></a>
    
    <div class="sectionL4">

    <h3>Association Object</h3>
    
    
<p>The association object pattern is a variant on many-to-many:  it specifically is used when your association table contains additional columns beyond those which are foreign keys to the left and right tables.  Instead of using the <code>secondary</code> argument, you map a new class directly to the association table.  The left side of the relation references the association object via one-to-many, and the association class references the right side via many-to-one.  <br></br>
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">left_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'left'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">right_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'right'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">association_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'association'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'left_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'left.id'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'right_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'right.id'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'data'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">left_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Association</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Association</span><span class="python_operator">, </span><span class="python_name">association_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'child'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">right_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The bi-directional version adds backrefs to both relations:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">left_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Association</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">"parent"</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Association</span><span class="python_operator">, </span><span class="python_name">association_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'child'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">"parent_assocs"</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">right_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Working with the association pattern in its direct form requires that child objects are associated with an association instance before being appended to the parent; similarly, access from parent to child goes through the association object:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># create parent, append a child via association
</span><span class="python_name">p </span><span class="python_operator">= </span><span class="python_name">Parent</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">a </span><span class="python_operator">= </span><span class="python_name">Association</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">a</span><span class="python_operator">.</span><span class="python_name">child </span><span class="python_operator">= </span><span class="python_name">Child</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">p</span><span class="python_operator">.</span><span class="python_name">children</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">a</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># iterate through child objects via association, including association 
# attributes
</span><span class="python_keyword">for </span><span class="python_name">assoc </span><span class="python_keyword">in </span><span class="python_name">p</span><span class="python_operator">.</span><span class="python_name">children</span><span class="python_operator">:
    </span><span class="python_keyword">print </span><span class="python_name">assoc</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">
    </span><span class="python_keyword">print </span><span class="python_name">assoc</span><span class="python_operator">.</span><span class="python_name">child</span><span class="python_operator">
</span></pre>
    </div>
<p>To enhance the association object pattern such that direct access to the <code>Association</code> object is optional, SQLAlchemy provides the <a href="#plugins_associationproxy">associationproxy</a>.
</p>
<p><strong>Important Note</strong>:  it is strongly advised that the <code>secondary</code> table argument not be combined with the Association Object pattern, unless the <code>relation()</code> which contains the <code>secondary</code> argument is marked <code>viewonly=True</code>.  Otherwise, SQLAlchemy may persist conflicting data to the underlying association table since it is represented by two conflicting mappings.  The Association Proxy pattern should be favored in the case where access to the underlying association data is only sometimes needed.
</p>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_relation_selfreferential"></a>
    
    <div class="sectionL3">

    <h3>Adjacency List Relationships</h3>
    
    

<p>The <strong>adjacency list</strong> pattern is a common relational pattern whereby a table contains a foreign key reference to itself.  This is the most common and simple way to represent hierarchical data in flat tables.  The other way is the "nested sets" model, sometimes called "modified preorder".  Despite what many online articles say about modified preorder, the adjacency list model is probably the most appropriate pattern for the large majority of hierarchical storage needs, for reasons of concurrency, reduced complexity, and that modified preorder has little advantage over an application which can fully load subtrees into the application space.
</p>
<p>SQLAlchemy commonly refers to an adjacency list relation as a <strong>self-referential mapper</strong>.  In this example, we'll work with a single table called <code>treenodes</code> to represent a tree structure:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">nodes </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'treenodes'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'parent_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'treenodes.id'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'data'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>A graph such as the following:
</p>

    

    <div class="sliding_code">
        <pre>
root --+---> child1
       +---> child2 --+--> subchild1
       |              +--> subchild2
       +---> child3
</pre>
    </div>
<p>Would be represented with data such as:
</p>

    

    <div class="sliding_code">
        <pre>
id       parent_id     data
---      -------       ----
1        NULL          root
2        1             child1
3        1             child2
4        3             subchild1
5        3             subchild2
6        1             child3
</pre>
    </div>
<p>SQLAlchemy's <code>mapper()</code> configuration for a self-referential one-to-many relationship is exactly like a "normal" one-to-many relationship.  When SQLAlchemy encounters the foreign key relation from <code>treenodes</code> to <code>treenodes</code>, it assumes one-to-many unless told otherwise:    <br></br>
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># entity class
</span><span class="python_keyword">class </span><span class="python_name">Node</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">, </span><span class="python_name">nodes</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>To create a many-to-one relationship from child to parent, an extra indicator of the "remote side" is added, which contains the <code>Column</code> object or objects indicating the remote side of the relation:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">, </span><span class="python_name">nodes</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'parent'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">, </span><span class="python_name">remote_side</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">nodes</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">])</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>And the bi-directional version combines both:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">, </span><span class="python_name">nodes</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_name">backref</span><span class="python_enclosure">(</span><span class="python_literal">'parent'</span><span class="python_operator">, </span><span class="python_name">remote_side</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">nodes</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">]))</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>There are several examples included with SQLAlchemy illustrating self-referential strategies; these include <a href='http://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/examples/adjacencytree/basic_tree.py'>basic_tree.py</a> and <a href='http://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/examples/elementtree/optimized_al.py'>optimized_al.py</a>, the latter of which illustrates how to persist and search XML documents in conjunction with <a href='http://effbot.org/zone/element-index.htm'>ElementTree</a>.
</p>

    
    <A name="advdatamapping_relation_selfreferential_query"></a>
    
    <div class="sectionL4">

    <h3>Self-Referential Query Strategies</h3>
    
    
<p>Querying self-referential structures is done in the same way as any other query in SQLAlchemy, such as below, we query for any node whose <code>data</code> attrbibute stores the value <code>child2</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># get all nodes named 'child2'
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'child2'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>On the subject of joins, i.e. those described in <a href="#datamapping_joins">Querying with Joins</a>, self-referential structures require the usage of aliases so that the same table can be referenced multiple times within the FROM clause of the query.   Aliasing can be done either manually using the <code>nodes</code> <code>Table</code> object as a source of aliases:
</p>

    

    <div class="code">
        <pre>
<span class="python_comment"># get all nodes named 'subchild1' with a parent named 'child2'
</span><span class="python_name">nodealias </span><span class="python_operator">= </span><span class="python_name">nodes</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_91', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'subchild1'</span><span class="python_enclosure">)</span><span class="python_operator">.\
    </span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">parent_id</span><span class="python_operator">==</span><span class="python_name">nodealias</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">, </span><span class="python_name">nodealias</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'child2'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_91_div" class="codepop" style="display:none;">SELECT treenodes.id AS treenodes_id, treenodes.parent_id AS treenodes_parent_id, treenodes.data AS treenodes_data <br/>
FROM treenodes, treenodes AS treenodes_1 <br/>
WHERE treenodes.data = ? AND treenodes.parent_id = treenodes_1.id AND treenodes_1.data = ? ORDER BY treenodes.oid<br/>
['subchild1', 'child2']</div><pre><span class="python_operator"></span></pre>
    </div>
<p>or automatically, using <code>join()</code> with <code>aliased=True</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_comment"># get all nodes named 'subchild1' with a parent named 'child2'
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_92', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'subchild1'</span><span class="python_enclosure">)</span><span class="python_operator">.\
    </span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'parent'</span><span class="python_operator">, </span><span class="python_name">aliased</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'child2'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_92_div" class="codepop" style="display:none;">SELECT treenodes.id AS treenodes_id, treenodes.parent_id AS treenodes_parent_id, treenodes.data AS treenodes_data <br/>
FROM treenodes JOIN treenodes AS treenodes_1 ON treenodes_1.id = treenodes.parent_id <br/>
WHERE treenodes.data = ? AND treenodes_1.data = ? ORDER BY treenodes.oid<br/>
['subchild1', 'child2']</div><pre><span class="python_operator"></span></pre>
    </div>
<p>To add criterion to multiple points along a longer join, use <code>from_joinpoint=True</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_comment"># get all nodes named 'subchild1' with a parent named 'child2' and a grandparent 'root'
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_93', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'subchild1'</span><span class="python_enclosure">)</span><span class="python_operator">.\
    </span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'parent'</span><span class="python_operator">, </span><span class="python_name">aliased</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'child2'</span><span class="python_enclosure">)</span><span class="python_operator">.\
    </span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'parent'</span><span class="python_operator">, </span><span class="python_name">aliased</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">from_joinpoint</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">==</span><span class="python_literal">'root'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_93_div" class="codepop" style="display:none;">SELECT treenodes.id AS treenodes_id, treenodes.parent_id AS treenodes_parent_id, treenodes.data AS treenodes_data <br/>
FROM treenodes JOIN treenodes AS treenodes_1 ON treenodes_1.id = treenodes.parent_id JOIN treenodes AS treenodes_2 ON treenodes_2.id = treenodes_1.parent_id <br/>
WHERE treenodes.data = ? AND treenodes_1.data = ? AND treenodes_2.data = ? ORDER BY treenodes.oid<br/>
['subchild1', 'child2', 'root']</div><pre><span class="python_operator"></span></pre>
    </div>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_selfreferential_eagerloading"></a>
    
    <div class="sectionL4">

    <h3>Configuring Eager Loading</h3>
    
    
<p>Eager loading of relations occurs using joins or outerjoins from parent to child table during a normal query operation, such that the parent and its child collection can be populated from a single SQL statement.  SQLAlchemy's eager loading uses aliased tables in all cases when joining to related items, so it is compatible with self-referential joining.  However, to use eager loading with a self-referential relation, SQLAlchemy needs to be told how many levels deep it should join; otherwise the eager load will not take place.  This depth setting is configured via <code>join_depth</code>:
</p>

    

    <div class="code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">, </span><span class="python_name">nodes</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_operator">, </span><span class="python_name">lazy</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_operator">, </span><span class="python_name">join_depth</span><span class="python_operator">=</span><span class="python_number">2</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_94', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Node</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_94_div" class="codepop" style="display:none;">SELECT treenodes_1.id AS treenodes_1_id, treenodes_1.parent_id AS treenodes_1_parent_id, treenodes_1.data AS treenodes_1_data, treenodes_2.id AS treenodes_2_id, treenodes_2.parent_id AS treenodes_2_parent_id, treenodes_2.data AS treenodes_2_data, treenodes.id AS treenodes_id, treenodes.parent_id AS treenodes_parent_id, treenodes.data AS treenodes_data <br/>
FROM treenodes LEFT OUTER JOIN treenodes AS treenodes_2 ON treenodes.id = treenodes_2.parent_id LEFT OUTER JOIN treenodes AS treenodes_1 ON treenodes_2.id = treenodes_1.parent_id ORDER BY treenodes.oid, treenodes_2.oid, treenodes_1.oid<br/>
[]</div><pre><span class="python_operator"></span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_relation_customjoin"></a>
    
    <div class="sectionL3">

    <h3>Specifying Alternate Join Conditions to relation()</h3>
    
    

<p>The <code>relation()</code> function uses the foreign key relationship between the parent and child tables to formulate the <strong>primary join condition</strong> between parent and child; in the case of a many-to-many relationship it also formulates the <strong>secondary join condition</strong>.  If you are working with a <code>Table</code> which has no <code>ForeignKey</code> objects on it (which can be the case when using reflected tables with MySQL), or if the join condition cannot be expressed by a simple foreign key relationship, use the <code>primaryjoin</code> and possibly <code>secondaryjoin</code> conditions to create the appropriate relationship.
</p>
<p>In this example we create a relation <code>boston_addresses</code> which will only load the user addresses with a city of "Boston":
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'boston_addresses' </span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">primaryjoin</span><span class="python_operator">=</span>
                <span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
                <span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">city</span><span class="python_operator">==</span><span class="python_literal">'Boston'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Many to many relationships can be customized by one or both of <code>primaryjoin</code> and <code>secondaryjoin</code>, shown below with just the default many-to-many relationship explicitly set:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_operator">, </span><span class="python_name">keywords_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'keywords'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_operator">, </span><span class="python_name">secondary</span><span class="python_operator">=</span><span class="python_name">userkeywords_table</span><span class="python_operator">,</span>
        <span class="python_name">primaryjoin</span><span class="python_operator">=</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">userkeywords_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">,</span>
        <span class="python_name">secondaryjoin</span><span class="python_operator">=</span><span class="python_name">userkeywords_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">keyword_id</span><span class="python_operator">==</span><span class="python_name">keywords_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">keyword_id</span>
        <span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>

    
    <A name="advdatamapping_relation_customjoin_fks"></a>
    
    <div class="sectionL4">

    <h3>Specifying Foreign Keys</h3>
    
    
<p>When using <code>primaryjoin</code> and <code>secondaryjoin</code>, SQLAlchemy also needs to be aware of which columns in the relation reference the other.  In most cases, a <code>Table</code> construct will have <code>ForeignKey</code> constructs which take care of this; however, in the case of reflected tables on a database that does not report FKs (like MySQL ISAM) or when using join conditions on columns that don't have foreign keys, the <code>relation()</code> needs to be told specifically which columns are "foreign" using the <code>foreign_keys</code> collection:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'addresses' </span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span>
         <span class="python_name">primaryjoin</span><span class="python_operator">=</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">,</span>
         <span class="python_name">foreign_keys</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">])</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_customjoin_properties"></a>
    
    <div class="sectionL4">

    <h3>Building Query-Enabled Properties</h3>
    
    
<p>Very ambitious custom join conditions may fail to be directly persistable, and in some cases may not even load correctly.  To remove the persistence part of the equation, use the flag <code>viewonly=True</code> on the <code>relation()</code>, which establishes it as a read-only attribute (data written to the collection will be ignored on flush()).  However, in extreme cases, consider using a regular Python property in conjunction with <code>Query</code> as follows:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">_get_addresses</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">object_session</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">with_parent</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_operator">...</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_name">addresses </span><span class="python_operator">= </span><span class="python_name">property</span><span class="python_enclosure">(</span><span class="python_name">_get_addresses</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_customjoin_multiplejoin"></a>
    
    <div class="sectionL4">

    <h3>Multiple Relations against the Same Parent/Child</h3>
    
    
<p>Theres no restriction on how many times you can relate from parent to child.  SQLAlchemy can usually figure out what you want, particularly if the join conditions are straightforward.  Below we add a <code>newyork_addresses</code> attribute to complement the <code>boston_addresses</code> attribute:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'boston_addresses' </span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">primaryjoin</span><span class="python_operator">=</span>
                <span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
                <span class="python_name">Addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">city</span><span class="python_operator">==</span><span class="python_literal">'Boston'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_literal">'newyork_addresses' </span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">primaryjoin</span><span class="python_operator">=</span>
                <span class="python_name">and_</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">, </span>
                <span class="python_name">Addresses</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">city</span><span class="python_operator">==</span><span class="python_literal">'New York'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_relation_collections"></a>
    
    <div class="sectionL3">

    <h3>Alternate Collection Implementations</h3>
    
    

<p>Mapping a one-to-many or many-to-many relationship results in a collection of values accessible through an attribute on the parent instance.  By default, this collection is a <code>list</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_name">children </span><span class="python_operator">= </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">parent </span><span class="python_operator">= </span><span class="python_name">Parent</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">parent</span><span class="python_operator">.</span><span class="python_name">children</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_enclosure">())</span><span class="python_operator">
</span><span class="python_keyword">print </span><span class="python_name">parent</span><span class="python_operator">.</span><span class="python_name">children</span><span class="python_enclosure">[</span><span class="python_number">0</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>Collections are not limited to lists.  Sets, mutable sequences and almost any other Python object that can act as a container can be used in place of the default list.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># use a set
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_name">children </span><span class="python_operator">= </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">collection_class</span><span class="python_operator">=</span><span class="python_name">set</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">parent </span><span class="python_operator">= </span><span class="python_name">Parent</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">child </span><span class="python_operator">= </span><span class="python_name">Child</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">parent</span><span class="python_operator">.</span><span class="python_name">children</span><span class="python_operator">.</span><span class="python_name">add</span><span class="python_enclosure">(</span><span class="python_name">child</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">assert </span><span class="python_name">child </span><span class="python_keyword">in </span><span class="python_name">parent</span><span class="python_operator">.</span><span class="python_name">children</span><span class="python_operator">
</span></pre>
    </div>

    
    <A name="advdatamapping_relation_collections_custom"></a>
    
    <div class="sectionL4">

    <h3>Custom Collection Implementations</h3>
    
    
<p>You can use your own types for collections as well.  For most cases, simply inherit from <code>list</code> or <code>set</code> and add the custom behavior.
</p>
<p>Collections in SQLAlchemy are transparently <em>instrumented</em>.  Instrumentation means that normal operations on the collection are tracked and result in changes being written to the database at flush time.  Additionally, collection operations can fire <em>events</em> which indicate some secondary operation must take place.  Examples of a secondary operation include saving the child item in the parent's <code>Session</code> (i.e. the <code>save-update</code> cascade), as well as synchronizing the state of a bi-directional relationship (i.e. a <code>backref</code>).
</p>
<p>The collections package understands the basic interface of lists, sets and dicts and will automatically apply instrumentation to those built-in types and their subclasses.  Object-derived types that implement a basic collection interface are detected and instrumented via duck-typing:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">ListLike</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data </span><span class="python_operator">= </span><span class="python_enclosure">[]</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">remove</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">.</span><span class="python_name">remove</span><span class="python_enclosure">(</span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">extend</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">items</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">.</span><span class="python_name">extend</span><span class="python_enclosure">(</span><span class="python_name">items</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__iter__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">iter</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">foo</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_literal">'foo'</span><span class="python_operator">
</span></pre>
    </div>
<p><code>append</code>, <code>remove</code>, and <code>extend</code> are known list-like methods, and will be instrumented automatically.  <code>__iter__</code> is not a mutator method and won't be instrumented, and <code>foo</code> won't be either.
</p>
<p>Duck-typing (i.e. guesswork) isn't rock-solid, of course, so you can be explicit about the interface you are implementing by providing an <code>__emulates__</code> class attribute:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">SetLike</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__emulates__ </span><span class="python_operator">= </span><span class="python_name">set</span><span class="python_operator">
</span>
    <span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data </span><span class="python_operator">= </span><span class="python_name">set</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">.</span><span class="python_name">add</span><span class="python_enclosure">(</span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">remove</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">.</span><span class="python_name">remove</span><span class="python_enclosure">(</span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__iter__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">iter</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>This class looks list-like because of <code>append</code>, but <code>__emulates__</code> forces it to set-like.  <code>remove</code> is known to be part of the set interface and will be instrumented.
</p>
<p>But this class won't work quite yet: a little glue is needed to adapt it for use by SQLAlchemy.  The ORM needs to know which methods to use to append, remove and iterate over members of the collection.  When using a type like <code>list</code> or <code>set</code>, the appropriate methods are well-known and used automatically when present. This set-like class does not provide the expected <code>add</code> method, so we must supply an explicit mapping for the ORM via a decorator.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_collections_decorators"></a>
    
    <div class="sectionL4">

    <h3>Annotating Custom Collections via Decorators</h3>
    
    
<p>Decorators can be used to tag the individual methods the ORM needs to manage collections.  Use them when your class doesn't quite meet the regular interface for its container type, or you simply would like to use a different method to get the job done.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">collections </span><span class="python_keyword">import </span><span class="python_name">collection</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">SetLike</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__emulates__ </span><span class="python_operator">= </span><span class="python_name">set</span><span class="python_operator">
</span>
    <span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data </span><span class="python_operator">= </span><span class="python_name">set</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
    <span class="python_operator">@</span><span class="python_name">collection</span><span class="python_operator">.</span><span class="python_name">appender</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">.</span><span class="python_name">add</span><span class="python_enclosure">(</span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">remove</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_operator">.</span><span class="python_name">remove</span><span class="python_enclosure">(</span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">__iter__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">iter</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">data</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>And that's all that's needed to complete the example.  SQLAlchemy will add instances via the <code>append</code> method.  <code>remove</code> and <code>__iter__</code> are the default methods for sets and will be used for removing and iteration.  Default methods can be changed as well:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">collections </span><span class="python_keyword">import </span><span class="python_name">collection</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">MyList</span><span class="python_enclosure">(</span><span class="python_name">list</span><span class="python_enclosure">)</span><span class="python_operator">:
    @</span><span class="python_name">collection</span><span class="python_operator">.</span><span class="python_name">remover</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">zark</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">item</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_comment"># do something special...
</span>
    <span class="python_operator">@</span><span class="python_name">collection</span><span class="python_operator">.</span><span class="python_name">iterator</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">hey_use_this_instead_for_iteration</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_comment"># ...
</span><span class="python_operator"></span></pre>
    </div>
<p>There is no requirement to be list-, or set-like at all.  Collection classes can be any shape, so long as they have the append, remove and iterate interface marked for SQLAlchemy's use.  Append and remove methods will be called with a mapped entity as the single argument, and iterator methods are called with no arguments and must return an iterator.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_collections_dictcollections"></a>
    
    <div class="sectionL4">

    <h3>Dictionary-Based Collections</h3>
    
    
<p>A <code>dict</code> can be used as a collection, but a keying strategy is needed to map entities loaded by the ORM to key, value pairs.  The <a href="sqlalchemy_orm_collections.html#docstrings_sqlalchemy.orm.collections">collections</a> package provides several built-in types for dictionary-based collections:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">collections </span><span class="python_keyword">import </span><span class="python_name">column_mapped_collection</span><span class="python_operator">, </span><span class="python_name">attribute_mapped_collection</span><span class="python_operator">, </span><span class="python_name">mapped_collection</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_operator">, </span><span class="python_name">items_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_comment"># key by column</span>
    <span class="python_literal">'notes'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Note</span><span class="python_operator">, </span><span class="python_name">collection_class</span><span class="python_operator">=</span><span class="python_name">column_mapped_collection</span><span class="python_enclosure">(</span><span class="python_name">notes_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">keyword</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_comment"># or named attribute </span>
    <span class="python_literal">'notes2'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Note</span><span class="python_operator">, </span><span class="python_name">collection_class</span><span class="python_operator">=</span><span class="python_name">attribute_mapped_collection</span><span class="python_enclosure">(</span><span class="python_literal">'keyword'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_comment"># or any callable</span>
    <span class="python_literal">'notes3'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Note</span><span class="python_operator">, </span><span class="python_name">collection_class</span><span class="python_operator">=</span><span class="python_name">mapped_collection</span><span class="python_enclosure">(</span><span class="python_keyword">lambda </span><span class="python_name">entity</span><span class="python_operator">: </span><span class="python_name">entity</span><span class="python_operator">.</span><span class="python_name">a </span><span class="python_operator">+ </span><span class="python_name">entity</span><span class="python_operator">.</span><span class="python_name">b</span><span class="python_enclosure">))</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_comment"># ...
</span><span class="python_name">item </span><span class="python_operator">= </span><span class="python_name">Item</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">item</span><span class="python_operator">.</span><span class="python_name">notes</span><span class="python_enclosure">[</span><span class="python_literal">'color'</span><span class="python_enclosure">] </span><span class="python_operator">= </span><span class="python_name">Note</span><span class="python_enclosure">(</span><span class="python_literal">'color'</span><span class="python_operator">, </span><span class="python_literal">'blue'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">print </span><span class="python_name">item</span><span class="python_operator">.</span><span class="python_name">notes</span><span class="python_enclosure">[</span><span class="python_literal">'color'</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>These functions each provide a <code>dict</code> subclass with decorated <code>set</code> and <code>remove</code> methods and the keying strategy of your choice.
</p>
<p>The <b>collections.MappedCollection</b> class can be used as a base class for your custom types or as a mix-in to quickly add <code>dict</code> collection support to other classes.  It uses a keying function to delegate to <code>__setitem__</code> and <code>__delitem__</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">util </span><span class="python_keyword">import </span><span class="python_name">OrderedDict</span><span class="python_operator">
</span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">collections </span><span class="python_keyword">import </span><span class="python_name">MappedCollection</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">NodeMap</span><span class="python_enclosure">(</span><span class="python_name">OrderedDict</span><span class="python_operator">, </span><span class="python_name">MappedCollection</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_literal">"""Holds 'Node' objects, keyed by the 'name' attribute with insert order maintained."""</span><span class="python_operator">
</span>
    <span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, *</span><span class="python_name">args</span><span class="python_operator">, **</span><span class="python_name">kw</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">MappedCollection</span><span class="python_operator">.</span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">keyfunc</span><span class="python_operator">=</span><span class="python_keyword">lambda </span><span class="python_name">node</span><span class="python_operator">: </span><span class="python_name">node</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">OrderedDict</span><span class="python_operator">.</span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, *</span><span class="python_name">args</span><span class="python_operator">, **</span><span class="python_name">kw</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The ORM understands the <code>dict</code> interface just like lists and sets, and will automatically instrument all dict-like methods if you choose to subclass <code>dict</code> or provide dict-like collection behavior in a duck-typed class.  You must decorate appender and remover methods, however- there are no compatible methods in the basic dictionary interface for SQLAlchemy to use by default.  Iteration will go through <code>itervalues()</code> unless otherwise decorated.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_collections_adv_collections"></a>
    
    <div class="sectionL4">

    <h3>Instrumentation and Custom Types</h3>
    
    
<p>Many custom types and existing library classes can be used as a entity collection type as-is without further ado.  However, it is important to note that the instrumentation process <em>will</em> modify the type, adding decorators around methods automatically.
</p>
<p>The decorations are lightweight and no-op outside of relations, but they do add unneeded overhead when triggered elsewhere.  When using a library class as a collection, it can be good practice to use the "trivial subclass" trick to restrict the decorations to just your usage in relations.  For example:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MyAwesomeList</span><span class="python_enclosure">(</span><span class="python_name">some</span><span class="python_operator">.</span><span class="python_name">great</span><span class="python_operator">.</span><span class="python_name">library</span><span class="python_operator">.</span><span class="python_name">AwesomeList</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_comment"># ... relation(..., collection_class=MyAwesomeList)
</span><span class="python_operator"></span></pre>
    </div>
<p>The ORM uses this approach for built-ins, quietly substituting a trivial subclass when a <code>list</code>, <code>set</code> or <code>dict</code> is used directly.
</p>
<p>The collections package provides additional decorators and support for authoring custom types.  See the <a href="sqlalchemy_orm_collections.html#docstrings_sqlalchemy.orm.collections">package documentation</a> for more information and discussion of advanced usage and Python 2.3-compatible decoration options.
</p>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_relation_strategies"></a>
    
    <div class="sectionL3">

    <h3>Configuring Loader Strategies: Lazy Loading, Eager Loading</h3>
    
    

<p>In the <a href="#datamapping">Object Relational Tutorial</a>, we introduced the concept of <strong>Eager Loading</strong>.  We used an <code>option</code> in conjunction with the <code>Query</code> object in order to indicate that a relation should be loaded at the same time as the parent, within a single SQL query:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_95', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">jack </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"> </span></pre><div id="popbox_95_div" class="codepop" style="display:none;">SELECT addresses_1.id AS addresses_1_id, addresses_1.email_address AS addresses_1_email_address, <br/>
addresses_1.user_id AS addresses_1_user_id, users.id AS users_id, users.name AS users_name, <br/>
users.fullname AS users_fullname, users.password AS users_password <br/>
FROM users LEFT OUTER JOIN addresses AS addresses_1 ON users.id = addresses_1.user_id <br/>
WHERE users.name = ? ORDER BY users.oid, addresses_1.oid<br/>
['jack']</div><pre><span class="python_operator"></span></pre>
    </div>
<p>By default, all relations are <strong>lazy loading</strong>.  The scalar or collection attribute associated with a <code>relation()</code> contains a trigger which fires the first time the attribute is accessed, which issues a SQL call at that point:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_96', 'show', 'hide')" class="codepoplink">sql</a>&gt;&gt;&gt; </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator"></span></pre><div id="popbox_96_div" class="codepop" style="display:none;">SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id <br/>
FROM addresses <br/>
WHERE ? = addresses.user_id ORDER BY addresses.oid<br/>
[5]</div><pre><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">u'jack@google.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_literal">u'j25@yahoo.com'</span><span class="python_enclosure">)</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>The default <strong>loader strategy</strong> for any <code>relation()</code> is configured by the <code>lazy</code> keyword argument, which defaults to <code>True</code>.  Below we set it as <code>False</code> so that the <code>children</code> relation is eager loading:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># eager load 'children' attribute
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_operator">, </span><span class="python_name">parent_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Child</span><span class="python_operator">, </span><span class="python_name">lazy</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>The loader strategy can be changed from lazy to eager as well as eager to lazy using the <code>eagerload()</code> and <code>lazyload()</code> query options:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># set children to load lazily
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">lazyload</span><span class="python_enclosure">(</span><span class="python_literal">'children'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># set children to load eagerly
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'children'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>To reference a relation that is deeper than one level, separate the names by periods:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Parent</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'foo.bar.bat'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>When using dot-separated names with <code>eagerload()</code>, option applies <strong>only</strong> to the actual attribute named, and <strong>not</strong> its ancestors.  For example, suppose a mapping from <code>A</code> to <code>B</code> to <code>C</code>, where the relations, named <code>atob</code> and <code>btoc</code>, are both lazy-loading.  A statement like the following:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">A</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'atob.btoc'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>will load only <code>A</code> objects to start.  When the <code>atob</code> attribute on each <code>A</code> is accessed, the returned <code>B</code> objects will <em>eagerly</em> load their <code>C</code> objects. 
</p>
<p>Therefore, to modify the eager load to load both <code>atob</code> as well as <code>btoc</code>, place eagerloads for both:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">A</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'atob'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'atob.btoc'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>or more simply just use <code>eagerload_all()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">A</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload_all</span><span class="python_enclosure">(</span><span class="python_literal">'atob.btoc'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>There are two other loader strategies available, <strong>dynamic loading</strong> and <strong>no loading</strong>; these are described in <a href="#advdatamapping_relation_largecollections">Working with Large Collections</a>.
</p>

    
    <A name="advdatamapping_relation_strategies_combining"></a>
    
    <div class="sectionL4">

    <h3>Combining Eager Loads with Statement/Result Set Queries</h3>
    
    
<p>When full statement or result-set loads are used with <code>Query</code>, SQLAlchemy does not affect the SQL query itself, and therefore has no way of tacking on its own <code>LEFT [OUTER] JOIN</code> conditions that are normally used to eager load relationships.  If the query being constructed is created in such a way that it returns rows not just from a parent table (or tables) but also returns rows from child tables, the result-set mapping can be notified as to which additional properties are contained within the result set.  This is done using the <code>contains_eager()</code> query option, which specifies the name of the relationship to be eagerly loaded.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># mapping is the users-&gt;addresses mapping
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'addresses'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_comment"># define a query on USERS with an outer join to ADDRESSES
</span><span class="python_name">statement </span><span class="python_operator">= </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">addresses_table</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">use_labels</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># construct a Query object which expects the "addresses" results 
</span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">contains_eager</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_comment"># get results normally
</span><span class="python_name">r </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">from_statement</span><span class="python_enclosure">(</span><span class="python_name">statement</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>If the "eager" portion of the statement is "aliased", the <code>alias</code> keyword argument to <code>contains_eager()</code> may be used to indicate it.  This is a string alias name or reference to an actual <code>Alias</code> object:
</p>

    

    <div class="code">
        <pre>
<span class="python_comment"># use an alias of the addresses table
</span><span class="python_name">adalias </span><span class="python_operator">= </span><span class="python_name">addresses_table</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">(</span><span class="python_literal">'adalias'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># define a query on USERS with an outer join to adalias
</span><span class="python_name">statement </span><span class="python_operator">= </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">adalias</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">use_labels</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># construct a Query object which expects the "addresses" results 
</span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">contains_eager</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_operator">, </span><span class="python_name">alias</span><span class="python_operator">=</span><span class="python_name">adalias</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_comment"># get results normally
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_97', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">r </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">from_statement</span><span class="python_enclosure">(</span><span class="python_name">statement</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_97_div" class="codepop" style="display:none;">SELECT users.user_id AS users_user_id, users.user_name AS users_user_name, adalias.address_id AS adalias_address_id, <br/>
adalias.user_id AS adalias_user_id, adalias.email_address AS adalias_email_address, (...other columns...)<br/>
FROM users LEFT OUTER JOIN email_addresses AS adalias ON users.user_id = adalias.user_id</div><pre><span class="python_operator"></span></pre>
    </div>
<p>In the case that the main table itself is also aliased, the <code>contains_alias()</code> option can be used:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># define an aliased UNION called 'ulist'
</span><span class="python_name">statement </span><span class="python_operator">= </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_number">7</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">union</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">&gt;</span><span class="python_number">7</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">alias</span><span class="python_enclosure">(</span><span class="python_literal">'ulist'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># add on an eager load of "addresses"
</span><span class="python_name">statement </span><span class="python_operator">= </span><span class="python_name">statement</span><span class="python_operator">.</span><span class="python_name">outerjoin</span><span class="python_enclosure">(</span><span class="python_name">addresses</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">use_labels</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># create query, indicating "ulist" is an alias for the main table, "addresses" property should
# be eager loaded
</span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">create_session</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">contains_alias</span><span class="python_enclosure">(</span><span class="python_literal">'ulist'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">contains_eager</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_comment"># results
</span><span class="python_name">r </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">from_statement</span><span class="python_enclosure">(</span><span class="python_name">statement</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_relation_largecollections"></a>
    
    <div class="sectionL3">

    <h3>Working with Large Collections</h3>
    
    

<p>The default behavior of <code>relation()</code> is to fully load the collection of items in, as according to the loading strategy of the relation.  Additionally, the Session by default only knows how to delete objects which are actually present within the session.  When a parent instance is marked for deletion and flushed, the Session loads its full list of child items in so that they may either be deleted as well, or have their foreign key value set to null; this is to avoid constraint violations.  For large collections of child items, there are several strategies to bypass full loading of child items both at load time as well as deletion time.
</p>

    
    <A name="advdatamapping_relation_largecollections_dynamic"></a>
    
    <div class="sectionL4">

    <h3>Dynamic Relation Loaders</h3>
    
    
<p>The most useful by far is the <code>dynamic_loader()</code> relation.  This is a variant of <code>relation()</code> which returns a <code>Query</code> object in place of a collection when accessed.  <code>filter()</code> criterion may be applied as well as limits and offsets, either explicitly or via array slices:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'posts'</span><span class="python_operator">:</span><span class="python_name">dynamic_loader</span><span class="python_enclosure">(</span><span class="python_name">Post</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">jack </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># filter Jack's blog posts
</span><span class="python_name">posts </span><span class="python_operator">= </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">posts</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Post</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">headline</span><span class="python_operator">==</span><span class="python_literal">'this is a post'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># apply array slices
</span><span class="python_name">posts </span><span class="python_operator">= </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">posts</span><span class="python_enclosure">[</span><span class="python_number">5</span><span class="python_operator">:</span><span class="python_number">20</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>The dynamic relation supports limited write operations, via the <code>append()</code> and <code>remove()</code> methods.  Since the read side of the dynamic relation always queries the database, changes to the underlying collection will not be visible until the data has been flushed:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">oldpost </span><span class="python_operator">= </span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">posts</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Post</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">headline</span><span class="python_operator">==</span><span class="python_literal">'old post'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">posts</span><span class="python_operator">.</span><span class="python_name">remove</span><span class="python_enclosure">(</span><span class="python_name">oldpost</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">jack</span><span class="python_operator">.</span><span class="python_name">posts</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Post</span><span class="python_enclosure">(</span><span class="python_literal">'new post'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>To place a dynamic relation on a backref, use <code>lazy='dynamic'</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Post</span><span class="python_operator">, </span><span class="python_name">posts_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'user'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_name">backref</span><span class="python_enclosure">(</span><span class="python_literal">'posts'</span><span class="python_operator">, </span><span class="python_name">lazy</span><span class="python_operator">=</span><span class="python_literal">'dynamic'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that eager/lazy loading options cannot be used in conjunction dynamic relations at this time.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_largecollections_noload"></a>
    
    <div class="sectionL4">

    <h3>Setting Noload</h3>
    
    
<p>The opposite of the dynamic relation is simply "noload", specified using <code>lazy=None</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_operator">, </span><span class="python_name">table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_name">relation</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">MyOtherClass</span><span class="python_operator">, </span><span class="python_name">lazy</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, the <code>children</code> collection is fully writeable, and changes to it will be persisted to the database as well as locally available for reading at the time they are added.  However when instances of  <code>MyClass</code> are freshly loaded from the database, the <code>children</code> collection stays empty.
</p>


            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>



    
    <A name="advdatamapping_relation_largecollections_passivedelete"></a>
    
    <div class="sectionL4">

    <h3>Using Passive Deletes</h3>
    
    
<p>Use <code>passive_deletes=True</code> to disable child object loading on a DELETE operation, in conjunction with "ON DELETE (CASCADE|SET NULL)" on your database to automatically cascade deletes to child objects.   Note that "ON DELETE" is not supported on SQLite, and requires <code>InnoDB</code> tables when using MySQL:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mytable </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'mytable'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">myothertable </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'myothertable'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'parent_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">ForeignKeyConstraint</span><span class="python_enclosure">([</span><span class="python_literal">'parent_id'</span><span class="python_enclosure">]</span><span class="python_operator">,</span><span class="python_enclosure">[</span><span class="python_literal">'mytable.id'</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">ondelete</span><span class="python_operator">=</span><span class="python_literal">"CASCADE"</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">mmapper</span><span class="python_enclosure">(</span><span class="python_name">MyOtherClass</span><span class="python_operator">, </span><span class="python_name">myothertable</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'children'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">MyOtherClass</span><span class="python_operator">, </span><span class="python_name">cascade</span><span class="python_operator">=</span><span class="python_literal">"all, delete-orphan"</span><span class="python_operator">, </span><span class="python_name">passive_deletes</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>When <code>passive_deletes</code> is applied, the <code>children</code> relation will not be loaded into memory when an instance of <code>MyClass</code> is marked for deletion.  The <code>cascade=&quot;all, delete-orphan&quot;</code> <em>will</em> take effect for instances of <code>MyOtherClass</code> which are currently present in the session; however for instances of <code>MyOtherClass</code> which are not loaded, SQLAlchemy assumes that "ON DELETE CASCADE" rules will ensure that those rows are deleted by the database and that no foreign key violation will occur.
</p>



            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="advdatamapping_relation_mutablepks"></a>
    
    <div class="sectionL3">

    <h3>Mutable Primary Keys / Update Cascades</h3>
    
    

<p>As of SQLAlchemy 0.4.2, the primary key attributes of an instance can be changed freely, and will be persisted upon flush.  When the primary key of an entity changes, related items which reference the primary key must also be updated as well.  For databases which enforce referential integrity, it's required to use the database's ON UPDATE CASCADE functionality in order to propagate primary key changes.  For those which don't, the <code>passive_cascades</code> flag can be set to <code>False</code> which instructs SQLAlchemy to issue UPDATE statements individually.  The <code>passive_cascades</code> flag can also be <code>False</code> in conjunction with ON UPDATE CASCADE functionality, although in that case it issues UPDATE statements unnecessarily.
</p>
<p>A typical mutable primary key setup might look like:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">users </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'username'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'fullname'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">)))</span><span class="python_operator">
</span>
<span class="python_name">addresses </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'username'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'users.username'</span><span class="python_operator">, </span><span class="python_name">onupdate</span><span class="python_operator">=</span><span class="python_literal">"cascade"</span><span class="python_enclosure">)))</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'addresses'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">passive_updates</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>passive_updates is set to <code>True</code> by default.  Foreign key references to non-primary key columns are supported as well.
</p>




            <a href="#advdatamapping" class="totoc">back to section top</a>
    </div>




    </div>




    </div>



    
    
    <A name="unitofwork"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#advdatamapping">Mapper Configuration</a>

               |   
            Next: <a href="#dbengine">Database Engines</a>
    </div>

        <h2>Using the Session</h2>
    </div>


        








    
    <A name="unitofwork"></a>
    
    <div class="sectionL1">

    
    

<p>The <a href="#advdatamapping">Mapper</a> is the entrypoint to the configurational API of the SQLAlchemy object relational mapper.  But the primary object one works with when using the ORM is the <a href="sqlalchemy_orm_session.html#docstrings_sqlalchemy.orm.session_Session">Session</a>.
</p>


    
    <A name="unitofwork_what"></a>
    
    <div class="sectionL2">

    <h3>What does the Session do ?</h3>
    
    

<p>In the most general sense, the <code>Session</code> establishes all conversations with the database and represents a "holding zone" for all the mapped instances which you've loaded or created during its lifespan.  It implements the <a href='http://martinfowler.com/eaaCatalog/unitOfWork.html'>Unit of Work</a> pattern, which means it keeps track of all changes which occur, and is capable of <strong>flushing</strong> those changes to the database as appropriate.   Another important facet of the <code>Session</code> is that it's also maintaining <strong>unique</strong> copies of each instance, where "unique" means "only one object with a particular primary key" - this pattern is called the <a href='http://martinfowler.com/eaaCatalog/identityMap.html'>Identity Map</a>.
</p>
<p>Beyond that, the <code>Session</code> implements an interface which let's you move objects in or out of the session in a variety of ways, it provides the entryway to a <code>Query</code> object which is used to query the database for data, it is commonly used to provide transactional boundaries (though this is optional), and it also can serve as a configurational "home base" for one or more <code>Engine</code> objects, which allows various vertical and horizontal partitioning strategies to be achieved.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_getting"></a>
    
    <div class="sectionL2">

    <h3>Getting a Session</h3>
    
    

<p>The <code>Session</code> object exists just as a regular Python object, which can be directly instantiated.  However, it takes a fair amount of keyword options, several of which you probably want to set explicitly.  It's fairly inconvenient to deal with the "configuration" of a session every time you want to create one.  Therefore, SQLAlchemy recommends the usage of a helper function called <code>sessionmaker()</code>, which typically you call only once for the lifespan of an application.  This function creates a customized <code>Session</code> subclass for you, with your desired configurational arguments pre-loaded.  Then, whenever you need a new <code>Session</code>, you use your custom <code>Session</code> class with no arguments to create the session.
</p>


    
    <A name="unitofwork_getting_sessionmaker"></a>
    
    <div class="sectionL3">

    <h3>Using a sessionmaker() Configuration</h3>
    
    

<p>The usage of <code>sessionmaker()</code> is illustrated below:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">sessionmaker</span><span class="python_operator">
</span>
<span class="python_comment"># create a configured "Session" class
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># create a Session
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># work with sess
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">x</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># close when finished
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, the <code>sessionmaker</code> call creates a class for us, which we assign to the name <code>Session</code>.  This class is a subclass of the actual <code>sqlalchemy.orm.session.Session</code> class, which will instantiate with the arguments of <code>autoflush=True</code> and <code>transactional=True</code>.
</p>
<p>When you write your application, place the call to <code>sessionmaker()</code> somewhere global, and then make your new <code>Session</code> class available to the rest of your application.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_getting_binding"></a>
    
    <div class="sectionL3">

    <h3>Binding Session to an Engine or Connection</h3>
    
    

<p>In our previous example regarding <code>sessionmaker()</code>, nowhere did we specify how our session would connect to our database.  When the session is configured in this manner, it will look for a database engine to connect with via the <code>Table</code> objects that it works with - the chapter called <a href="#metadata_tables_binding">Binding MetaData to an Engine or Connection</a> describes how to associate <code>Table</code> objects directly with a source of database connections.
</p>
<p>However, it is often more straightforward to explicitly tell the session what database engine (or engines) you'd like it to communicate with.  This is particularly handy with multiple-database scenarios where the session can be used as the central point of configuration.  To achieve this, the constructor keyword <code>bind</code> is used for a basic single-database configuration:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># create engine
</span><span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://...'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># bind custom Session class to the engine
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_operator">, </span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># work with the session
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>One common issue with the above scenario is that an application will often organize its global imports before it ever connects to a database.  Since the <code>Session</code> class created by <code>sessionmaker()</code> is meant to be a global application object (note we are saying the session <em>class</em>, not a session <em>instance</em>), we may not have a <code>bind</code> argument available.  For this, the <code>Session</code> class returned by <code>sessionmaker()</code> supports post-configuration of all options, through its method <code>configure()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># configure Session class with desired options
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># later, we create the engine
</span><span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://...'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># associate it with our custom Session class
</span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">configure</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># work with the session
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>Session</code> also has the ability to be bound to multiple engines.   Descriptions of these scenarios are described in <b>unitofwork_partitioning</b>.
</p>


    
    <A name="unitofwork_getting_binding_connection"></a>
    
    <div class="sectionL4">

    <h3>Binding Session to a Connection</h3>
    
    

<p>The examples involving <code>bind</code> so far are dealing with the <code>Engine</code> object, which is, like the <code>Session</code> class itself, a global configurational object.  The <code>Session</code> can also be bound to an individual database <code>Connection</code>.  The reason you might want to do this is if your application controls the boundaries of transactions using distinct <code>Transaction</code> objects (these objects are described in <a href="#dbengine_transactions">Using Transactions with Connection</a>).  You'd have a transactional <code>Connection</code>, and then you'd want to work with an ORM-level <code>Session</code> which participates in that transaction.  Since <code>Connection</code> is definitely not a globally-scoped object in all but the most rudimental commandline applications, you can bind an individual <code>Session()</code> instance to a particular <code>Connection</code> not at class configuration time, but at session instance construction time:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># global application scope.  create Session class, engine
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://...'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator">...
</span>
<span class="python_comment"># local scope, such as within a controller function
</span>
<span class="python_comment"># connect to the database
</span><span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># bind an individual Session to the connection
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">connection</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="unitofwork_getting_createsession"></a>
    
    <div class="sectionL3">

    <h3>Using create_session()</h3>
    
    

<p>As an alternative to <code>sessionmaker()</code>, <code>create_session()</code> exists literally as a function which calls the normal <code>Session</code> constructor directly.  All arguments are passed through and the new <code>Session</code> object is returned:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session </span><span class="python_operator">= </span><span class="python_name">create_session</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">myengine</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>create_session()</code> function doesn't add any functionality to the regular <code>Session</code>, it just sets up a default argument set of <code>autoflush=False, transactional=False</code>.  But also, by calling <code>create_session()</code> instead of instantiating <code>Session</code> directly, you leave room in your application to change the type of session which the function creates.  For example, an application which is calling <code>create_session()</code> in many places, which is typical for a pre-0.4 application, can be changed to use a <code>sessionmaker()</code> by just assigning the return of <code>sessionmaker()</code> to the <code>create_session</code> name:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># change from:
</span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">create_session</span><span class="python_operator">
</span>
<span class="python_comment"># to:
</span><span class="python_name">create_session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="unitofwork_using"></a>
    
    <div class="sectionL2">

    <h3>Using the Session</h3>
    
    

<p>A typical session conversation starts with creating a new session, or acquiring one from an ongoing context.    You save new objects and load existing ones, make changes, mark some as deleted, and then persist your changes to the database.  If your session is transactional, you use <code>commit()</code> to persist any remaining changes and to commit the transaction.  If not, you call <code>flush()</code> which will flush any remaining data to the database.
</p>
<p>Below, we open a new <code>Session</code> using a configured <code>sessionmaker()</code>, make some changes, and commit:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># configured Session class
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">d </span><span class="python_operator">= </span><span class="python_name">Data</span><span class="python_enclosure">(</span><span class="python_name">value</span><span class="python_operator">=</span><span class="python_number">10</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">d</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">d2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Data</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">Data</span><span class="python_operator">.</span><span class="python_name">value</span><span class="python_operator">==</span><span class="python_number">15</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">d2</span><span class="python_operator">.</span><span class="python_name">value </span><span class="python_operator">= </span><span class="python_number">19</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>


    
    <A name="unitofwork_using_states"></a>
    
    <div class="sectionL3">

    <h3>Quickie Intro to Object States</h3>
    
    

<p>It's helpful to know the states which an instance can have within a session:
</p>
<ul>
 <li><p><em>Transient</em> - an instance that's not in a session, and is not saved to the database; i.e. it has no database identity.  The only relationship such an object has to the ORM is that its class has a <code>mapper()</code> associated with it.
</p>

 </li>

 <li><p><em>Pending</em> - when you <code>save()</code> a transient instance, it becomes pending.  It still wasn't actually flushed to the database yet, but it will be when the next flush occurs.
</p>

 </li>

 <li><p><em>Persistent</em> - An instance which is present in the session and has a record in the database.  You get persistent instances by either flushing so that the pending instances become persistent, or by querying the database for existing instances (or moving persistent instances from other sessions into your local session).
</p>

 </li>

 <li><p><em>Detached</em> - an instance which has a record in the database, but is not in any session.  Theres nothing wrong with this, and you can use objects normally when they're detached, <strong>except</strong> they will not be able to issue any SQL in order to load collections or attributes which are not yet loaded, or were marked as "expired".
</p>

 </li>
</ul>
<p>Knowing these states is important, since the <code>Session</code> tries to be strict about ambiguous operations (such as trying to save the same object to two different sessions at the same time).
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_faq"></a>
    
    <div class="sectionL3">

    <h3>Frequently Asked Questions</h3>
    
    

<ul>
 <li><p>When do I make a <code>sessionmaker</code> ?
</p>
<p>Just one time, somewhere in your application's global scope.  It should be looked upon as part of your application's configuration.  If your application has three .py files in a package, you could, for example, place the <code>sessionmaker</code> line in your <code>__init__.py</code> file; from that point on your other modules say "from mypackage import Session".   That way, everyone else just uses <code>Session()</code>, and the configuration of that session is controlled by that central point.
</p>
<p>If your application starts up, does imports, but does not know what database it's going to be connecting to, you can bind the <code>Session</code> at the "class" level to the engine later on, using <code>configure()</code>.
</p>
<p>In the examples in this section, we will frequently show the <code>sessionmaker</code> being created right above the line where we actually invoke <code>Session()</code>.  But that's just for example's sake !  In reality, the <code>sessionmaker</code> would be somewhere at the module level, and your individual <code>Session()</code> calls would be sprinkled all throughout your app, such as in a web application within each controller method.
</p>

 </li>

 <li><p>When do I make a <code>Session</code> ? 
</p>
<p>You typically invoke <code>Session()</code> when you first need to talk to your database, and want to save some objects or load some existing ones.  Then, you work with it, save your changes, and then dispose of it....or at the very least <code>close()</code> it.  It's not a "global" kind of object, and should be handled more like a "local variable", as it's generally <strong>not</strong> safe to use with concurrent threads.  Sessions are very inexpensive to make, and don't use any resources whatsoever until they are first used...so create some !
</p>
<p>There is also a pattern whereby you're using a <strong>contextual session</strong>, this is described later in <a href="#unitofwork_contextual">Contextual/Thread-local Sessions</a>.  In this pattern, a helper object is maintaining a <code>Session</code> for you, most commonly one that is local to the current thread (and sometimes also local to an application instance).  SQLAlchemy 0.4 has worked this pattern out such that it still <em>looks</em> like you're creating a new session as you need one...so in that case, it's still a guaranteed win to just say <code>Session()</code> whenever you want a session.  
</p>

 </li>

 <li><p>Is the Session a cache ? 
</p>
<p>Yeee...no.  It's somewhat used as a cache, in that it implements the identity map pattern, and stores objects keyed to their primary key.  However, it doesn't do any kind of query caching.  This means, if you say <code>session.query(Foo).filter_by(name='bar')</code>, even if <code>Foo(name='bar')</code> is right there, in the identity map, the session has no idea about that.  It has to issue SQL to the database, get the rows back, and then when it sees the primary key in the row, <em>then</em> it can look in the local identity map and see that the object is already there.  It's only when you say <code>query.get({some primary key})</code> that the <code>Session</code> doesn't have to issue a query.
</p>
<p>Additionally, the Session stores object instances using a weak reference by default.  This also defeats the purpose of using the Session as a cache, unless the <code>weak_identity_map</code> flag is set to <code>False</code>.
</p>
<p>The <code>Session</code> is not designed to be a global object from which everyone consults as a "registry" of objects.  That is the job of a <strong>second level cache</strong>.  A good library for implementing second level caching is <a href='http://www.danga.com/memcached/'>Memcached</a>.  It <em>is</em> possible to "sort of" use the <code>Session</code> in this manner, if you set it to be non-transactional and it never flushes any SQL, but it's not a terrific solution,  since if concurrent threads load the same objects at the same time, you may have multiple copies of the same objects present in collections.
</p>

 </li>

 <li><p>How can I get the <code>Session</code> for a certain object ?
</p>
<p>Use the <code>object_session()</code> classmethod available on <code>Session</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">object_session</span><span class="python_enclosure">(</span><span class="python_name">someobject</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>

 </li>

 <li><p>Is the session threadsafe ?
</p>
<p>Nope.  It has no thread synchronization of any kind built in, and particularly when you do a flush operation, it definitely is not open to concurrent threads accessing it, because it holds onto a single database connection at that point.  If you use a session which is non-transactional for read operations only, it's still not thread-"safe", but you also wont get any catastrophic failures either, since it opens and closes connections on an as-needed basis; it's just that different threads might load the same objects independently of each other, but only one will wind up in the identity map (however, the other one might still live in a collection somewhere).
</p>
<p>But the bigger point here is, you should not <em>want</em> to use the session with multiple concurrent threads.  That would be like having everyone at a restaurant all eat from the same plate.  The session is a local "workspace" that you use for a specific set of tasks; you don't want to, or need to, share that session with other threads who are doing some other task.  If, on the other hand, there are other threads  participating in the same task you are, such as in a desktop graphical application, then you would be sharing the session with those threads, but you also will have implemented a proper locking scheme (or your graphical framework does) so that those threads do not collide.
     <br></br>
</p>

 </li>
</ul>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_attributes"></a>
    
    <div class="sectionL3">

    <h3>Session Attributes</h3>
    
    

<p>The session provides a set of attributes and collection-oriented methods which allow you to view the current state of the session.
</p>
<p>The <strong>identity map</strong> is accessed by the <code>identity_map</code> attribute, which provides a dictionary interface.  The keys are "identity keys", which are attached to all persistent objects by the attribute <code>_instance_key</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">myobject</span><span class="python_operator">.</span><span class="python_name">_instance_key </span><span class="python_operator">
</span><span class="python_enclosure">(</span><span class="python_operator">&lt;</span><span class="python_keyword">class </span><span class="python_literal">'test.tables.User'</span><span class="python_operator">&gt;, </span><span class="python_enclosure">(</span><span class="python_number">7</span><span class="python_operator">,</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">myobject</span><span class="python_operator">.</span><span class="python_name">_instance_key </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">identity_map</span><span class="python_operator">
</span><span class="python_name">True</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">identity_map</span><span class="python_operator">.</span><span class="python_name">values</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">__main__</span><span class="python_operator">.</span><span class="python_name">User object at </span><span class="python_number">0x712630</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">__main__</span><span class="python_operator">.</span><span class="python_name">Address object at </span><span class="python_number">0x712a70</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>The identity map is a weak-referencing dictionary by default.  This means that objects which are dereferenced on the outside will be removed from the session automatically.  Note that objects which are marked as "dirty" will not fall out of scope until after changes on them have been flushed; special logic kicks in at the point of auto-removal which ensures that no pending changes remain on the object, else a temporary strong reference is created to the object.
</p>
<p>Some people prefer objects to stay in the session until explicitly removed in all cases; for this,  you can specify the flag <code>weak_identity_map=False</code> to the <code>create_session</code> or <code>sessionmaker</code> functions so that the <code>Session</code> will use a regular dictionary.
</p>
<p>While the <code>identity_map</code> accessor is currently the actual dictionary used by the <code>Session</code> to store instances, you should not add or remove items from this dictionary.  Use the session methods <code>save_or_update()</code> and <code>expunge()</code> to add or remove items.
</p>
<p>The Session also supports an iterator interface in order to see all objects in the identity map:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">for </span><span class="python_name">obj </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">:
    </span><span class="python_keyword">print </span><span class="python_name">obj</span><span class="python_operator">
</span></pre>
    </div>
<p>As well as <code>__contains__()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">if </span><span class="python_name">obj </span><span class="python_keyword">in </span><span class="python_name">session</span><span class="python_operator">:
    </span><span class="python_keyword">print </span><span class="python_literal">"Object is present"</span><span class="python_operator">
</span></pre>
    </div>
<p>The session is also keeping track of all newly created (i.e. pending) objects, all objects which have had changes since they were last loaded or saved (i.e. "dirty"), and everything that's been marked as deleted.  <br></br>
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># pending objects recently added to the Session
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">new</span><span class="python_operator">
</span>
<span class="python_comment"># persistent objects which currently have changes detected
# (this collection is now created on the fly each time the property is called)
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">dirty</span><span class="python_operator">
</span>
<span class="python_comment"># persistent objects that have been marked as deleted via session.delete(obj)
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">deleted</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_querying"></a>
    
    <div class="sectionL3">

    <h3>Querying</h3>
    
    

<p>The <code>query()</code> function takes one or more classes and/or mappers, along with an optional <code>entity_name</code> parameter, and returns a new <code>Query</code> object which will issue mapper queries within the context of this Session.  For each mapper is passed, the Query uses that mapper.  For each class, the Query will locate the primary mapper for the class using <code>class_mapper()</code>.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># query from a class
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># query with multiple classes, returns tuples
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">add_entity</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">join</span><span class="python_enclosure">(</span><span class="python_literal">'addresses'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># query from a mapper
</span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">usermapper</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">x </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># query from a class mapped with entity name 'alt_users'
</span><span class="python_name">q </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">entity_name</span><span class="python_operator">=</span><span class="python_literal">'alt_users'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">y </span><span class="python_operator">= </span><span class="python_name">q</span><span class="python_operator">.</span><span class="python_name">options</span><span class="python_enclosure">(</span><span class="python_name">eagerload</span><span class="python_enclosure">(</span><span class="python_literal">'orders'</span><span class="python_enclosure">))</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p><code>entity_name</code> is an optional keyword argument sent with a class object, in order to further qualify which primary mapper to be used; this only applies if there was a <code>Mapper</code> created with that particular class/entity name combination, else an exception is raised.  All of the methods on Session which take a class or mapper argument also take the <code>entity_name</code> argument, so that a given class can be properly matched to the desired primary mapper.
</p>
<p>All instances retrieved by the returned <code>Query</code> object will be stored as persistent instances within the originating <code>Session</code>.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_saving"></a>
    
    <div class="sectionL3">

    <h3>Saving New Instances</h3>
    
    

<p><code>save()</code> is called with a single transient instance as an argument, which is then added to the Session and becomes pending.  When the session is next flushed, the instance will be saved to the database.  If the given instance is not transient, meaning it is either attached to an existing Session or it has a database identity, an exception is raised.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">user1 </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'user1'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">user2 </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'user2'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">user1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">user2</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()     </span><span class="python_comment"># write changes to the database</span><span class="python_operator">
</span></pre>
    </div>
<p>There's also other ways to have objects saved to the session automatically; one is by using cascade rules, and the other is by using a contextual session.  Both of these are described later.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_updating/merging"></a>
    
    <div class="sectionL3">

    <h3>Updating/Merging Existing Instances</h3>
    
    

<p>The <code>update()</code> method is used when you have a detached instance, and you want to put it back into a <code>Session</code>.  Recall that "detached" means the object has a database identity.
</p>
<p>Since <code>update()</code> is a little picky that way, most people use <code>save_or_update()</code>, which checks for an <code>_instance_key</code> attribute, and based on whether it's there or not, calls either <code>save()</code> or <code>update()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># load user1 using session 1
</span><span class="python_name">user1 </span><span class="python_operator">= </span><span class="python_name">sess1</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">5</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># remove it from session 1
</span><span class="python_name">sess1</span><span class="python_operator">.</span><span class="python_name">expunge</span><span class="python_enclosure">(</span><span class="python_name">user1</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># move it into session 2
</span><span class="python_name">sess2</span><span class="python_operator">.</span><span class="python_name">save_or_update</span><span class="python_enclosure">(</span><span class="python_name">user1</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p><code>update()</code> is also an operation that can happen automatically using cascade rules, just like <code>save()</code>.  <br></br>
</p>
<p><code>merge()</code> on the other hand is a little like <code>update()</code>, except it creates a <strong>copy</strong> of the given instance in the session, and returns to you that instance; the instance you send it never goes into the session.  <code>merge()</code> is much fancier than <code>update()</code>; it will actually look to see if an object with the same primary key is already present in the session, and if not will load it by primary key.  Then, it will merge the attributes of the given object into the one which it just located.
</p>
<p>This method is useful for bringing in objects which may have been restored from a serialization, such as those stored in an HTTP session, where the object may be present in the session already:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># deserialize an object
</span><span class="python_name">myobj </span><span class="python_operator">= </span><span class="python_name">pickle</span><span class="python_operator">.</span><span class="python_name">loads</span><span class="python_enclosure">(</span><span class="python_name">mystring</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># "merge" it.  if the session already had this object in the 
# identity map, then you get back the one from the current session.
</span><span class="python_name">myobj </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">merge</span><span class="python_enclosure">(</span><span class="python_name">myobj</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p><code>merge()</code> includes an important option called <code>dont_load</code>.  When this boolean flag is set to <code>True</code>, the merge of a detached object will not force a <code>get()</code> of that object from the database.  Normally, <code>merge()</code> issues a <code>get()</code> for every existing object so that it can load the most recent state of the object, which is then modified according to the state of the given object.  With <code>dont_load=True</code>, the <code>get()</code> is skipped and <code>merge()</code> places an exact copy of the given object in the session.  This allows objects which were retrieved from a caching system to be copied back into a session without any SQL overhead being added.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_deleting"></a>
    
    <div class="sectionL3">

    <h3>Deleting</h3>
    
    

<p>The <code>delete</code> method places an instance into the Session's list of objects to be marked as deleted:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># mark two objects to be deleted
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">delete</span><span class="python_enclosure">(</span><span class="python_name">obj1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">delete</span><span class="python_enclosure">(</span><span class="python_name">obj2</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># commit (or flush)
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The big gotcha with <code>delete()</code> is that <strong>nothing is removed from collections</strong>.  Such as, if a <code>User</code> has a collection of three <code>Addresses</code>, deleting an <code>Address</code> will not remove it from <code>user.addresses</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">address </span><span class="python_operator">= </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">delete</span><span class="python_enclosure">(</span><span class="python_name">address</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">address </span><span class="python_keyword">in </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">
</span><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>
<p>The solution is to use proper cascading:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'addresses'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">cascade</span><span class="python_operator">=</span><span class="python_literal">"all, delete"</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_keyword">del </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_flushing"></a>
    
    <div class="sectionL3">

    <h3>Flushing</h3>
    
    

<p>This is the main gateway to what the <code>Session</code> does best, which is save everything !  It should be clear by now what a flush looks like:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>It also can be called with a list of objects; in this form, the flush operation will be limited only to the objects specified in the list:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># saves only user1 and address2.  all other modified
# objects remain present in the session.
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">([</span><span class="python_name">user1</span><span class="python_operator">, </span><span class="python_name">address2</span><span class="python_enclosure">])</span><span class="python_operator">
</span></pre>
    </div>
<p>This second form of flush should be used carefully as it will not necessarily locate other dependent objects within the session, whose database representation may have foreign constraint relationships with the objects being operated upon.
</p>
<p>Theres also a way to have <code>flush()</code> called automatically before each query; this is called "autoflush" and is described below.
</p>
<p>Note that when using a <code>Session</code> that has been placed into a transaction, the <code>commit()</code> method will also <code>flush()</code> the <code>Session</code> unconditionally before committing the transaction.  <br></br>
</p>
<p>Note that flush <strong>does not change</strong> the state of any collections or entity relationships in memory; for example, if you set a foreign key attribute <code>b_id</code> on object <code>A</code> with the identifier <code>B.id</code>, the change will be flushed to the database, but <code>A</code> will not have <code>B</code> added to its collection.  If you want to manipulate foreign key attributes directly, <code>refresh()</code> or <code>expire()</code> the objects whose state needs to be refreshed subsequent to flushing.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_autoflush"></a>
    
    <div class="sectionL3">

    <h3>Autoflush</h3>
    
    

<p>A session can be configured to issue <code>flush()</code> calls before each query.  This allows you to immediately have DB access to whatever has been saved to the session.  It's recommended to use autoflush with <code>transactional=True</code>, that way an unexpected flush call won't permanently save to the database:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">u1 </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">u1</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># reload user1
</span><span class="python_name">u2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'jack'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">assert </span><span class="python_name">u2 </span><span class="python_keyword">is </span><span class="python_name">u1</span><span class="python_operator">
</span>
<span class="python_comment"># commit session, flushes whatever is remaining
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Autoflush is particularly handy when using "dynamic" mapper relations, so that changes to the underlying collection are immediately available via its query interface.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_committing"></a>
    
    <div class="sectionL3">

    <h3>Committing</h3>
    
    

<p>The <code>commit()</code> method on <code>Session</code> is used specifically when the <code>Session</code> is in a transactional state.  The two ways that a session may be placed in a transactional state are to create it using the <code>transactional=True</code> option, or to call the <code>begin()</code> method.  <br></br>
</p>
<p><code>commit()</code> serves <strong>two</strong> purposes; it issues a <code>flush()</code> unconditionally to persist any remaining pending changes, and it issues a commit to all currently managed database connections.  In the typical case this is just a single connection.  After the commit, connection resources which were allocated by the <code>Session</code> are released.  This holds true even for a <code>Session</code> which specifies <code>transactional=True</code>; when such a session is committed, the next transaction is not "begun" until the next database operation occurs.
</p>
<p>See the section below on "Managing Transactions" for further detail.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_expunge"></a>
    
    <div class="sectionL3">

    <h3>Expunge / Clear</h3>
    
    

<p>Expunge removes an object from the Session, sending persistent instances to the detached state, and pending instances to the transient state:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">expunge</span><span class="python_enclosure">(</span><span class="python_name">obj1</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Use <code>expunge</code> when you'd like to remove an object altogether from memory, such as before calling <code>del</code> on it, which will prevent any "ghost" operations occurring when the session is flushed.
</p>
<p>This <code>clear()</code> method is equivalent to <code>expunge()</code>-ing everything from the Session:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">clear</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>However note that the <code>clear()</code> method does not reset any transactional state or connection resources; therefore what you usually want to call instead of <code>clear()</code> is <code>close()</code>.    <br></br>
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_closing"></a>
    
    <div class="sectionL3">

    <h3>Closing</h3>
    
    

<p>The <code>close()</code> method issues a <code>clear()</code>, and releases any transactional/connection resources.  When connections are returned to the connection pool, whatever transactional state exists is rolled back.
</p>
<p>When <code>close()</code> is called, the <code>Session</code> is in the same state as when it was first created, and is safe to be used again.  <code>close()</code> is especially important when using a contextual session, which remains in memory after usage.  By issuing <code>close()</code>, the session will be clean for the next request that makes use of it.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_using_refreshing"></a>
    
    <div class="sectionL3">

    <h3>Refreshing / Expiring</h3>
    
    

<p>To assist with the Session's "sticky" behavior of instances which are present, individual objects can have all of their attributes immediately re-loaded from the database, or marked as "expired" which will cause a re-load to occur upon the next access of any of the object's mapped attributes.  This includes all relationships, so lazy-loaders will be re-initialized, eager relationships will be repopulated.  Any changes marked on the object are discarded:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># immediately re-load attributes on obj1, obj2
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">refresh</span><span class="python_enclosure">(</span><span class="python_name">obj1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">refresh</span><span class="python_enclosure">(</span><span class="python_name">obj2</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># expire objects obj1, obj2, attributes will be reloaded
# on the next access:
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">expire</span><span class="python_enclosure">(</span><span class="python_name">obj1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">expire</span><span class="python_enclosure">(</span><span class="python_name">obj2</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p><code>refresh()</code> and <code>expire()</code> also support being passed a list of individual attribute names in which to be refreshed.  These names can reference any attribute, column-based or relation based:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># immediately re-load the attributes 'hello', 'world' on obj1, obj2
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">refresh</span><span class="python_enclosure">(</span><span class="python_name">obj1</span><span class="python_operator">, </span><span class="python_enclosure">[</span><span class="python_literal">'hello'</span><span class="python_operator">, </span><span class="python_literal">'world'</span><span class="python_enclosure">])</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">refresh</span><span class="python_enclosure">(</span><span class="python_name">obj2</span><span class="python_operator">, </span><span class="python_enclosure">[</span><span class="python_literal">'hello'</span><span class="python_operator">, </span><span class="python_literal">'world'</span><span class="python_enclosure">])</span><span class="python_operator">
</span>
<span class="python_comment"># expire the attributes 'hello', 'world' objects obj1, obj2, attributes will be reloaded
# on the next access:
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">expire</span><span class="python_enclosure">(</span><span class="python_name">obj1</span><span class="python_operator">, </span><span class="python_enclosure">[</span><span class="python_literal">'hello'</span><span class="python_operator">, </span><span class="python_literal">'world'</span><span class="python_enclosure">])</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">expire</span><span class="python_enclosure">(</span><span class="python_name">obj2</span><span class="python_operator">, </span><span class="python_enclosure">[</span><span class="python_literal">'hello'</span><span class="python_operator">, </span><span class="python_literal">'world'</span><span class="python_enclosure">])</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="unitofwork_cascades"></a>
    
    <div class="sectionL2">

    <h3>Cascades</h3>
    
    

<p>Mappers support the concept of configurable <em>cascade</em> behavior on <code>relation()</code>s.  This behavior controls how the Session should treat the instances that have a parent-child relationship with another instance that is operated upon by the Session.  Cascade is indicated as a comma-separated list of string keywords, with the possible values <code>all</code>, <code>delete</code>, <code>save-update</code>, <code>refresh-expire</code>, <code>merge</code>, <code>expunge</code>, and <code>delete-orphan</code>.
</p>
<p>Cascading is configured by setting the <code>cascade</code> keyword argument on a <code>relation()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Order</span><span class="python_operator">, </span><span class="python_name">order_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'items' </span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_operator">, </span><span class="python_name">items_table</span><span class="python_operator">, </span><span class="python_name">cascade</span><span class="python_operator">=</span><span class="python_literal">"all, delete-orphan"</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_literal">'customer' </span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">user_orders_table</span><span class="python_operator">, </span><span class="python_name">cascade</span><span class="python_operator">=</span><span class="python_literal">"save-update"</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>The above mapper specifies two relations, <code>items</code> and <code>customer</code>.  The <code>items</code> relationship specifies "all, delete-orphan" as its <code>cascade</code> value, indicating that all  <code>save</code>, <code>update</code>, <code>merge</code>, <code>expunge</code>, <code>refresh</code> <code>delete</code> and <code>expire</code> operations performed on a parent <code>Order</code> instance should also be performed on the child <code>Item</code> instances attached to it (<code>save</code> and <code>update</code> are cascaded using the <code>save_or_update()</code> method, so that the database identity of the instance doesn't matter).  The <code>delete-orphan</code> cascade value additionally indicates that if an <code>Item</code> instance is no longer associated with an <code>Order</code>, it should also be deleted.  The "all, delete-orphan" cascade argument allows a so-called <em>lifecycle</em> relationship between an <code>Order</code> and an <code>Item</code> object.
</p>
<p>The <code>customer</code> relationship specifies only the "save-update" cascade value, indicating most operations will not be cascaded from a parent <code>Order</code> instance to a child <code>User</code> instance, except for if the <code>Order</code> is attached with a particular session, either via the <code>save()</code>, <code>update()</code>, or <code>save-update()</code> method.
</p>
<p>Additionally, when a child item is attached to a parent item that specifies the "save-update" cascade value on the relationship, the child is automatically passed to <code>save_or_update()</code> (and the operation is further cascaded to the child item).
</p>
<p>Note that cascading doesn't do anything that isn't possible by manually calling Session methods on individual instances within a hierarchy, it merely automates common operations on a group of associated instances.
</p>
<p>The default value for <code>cascade</code> on <code>relation()</code>s is <code>save-update, merge</code>.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_managing"></a>
    
    <div class="sectionL2">

    <h3>Managing Transactions</h3>
    
    

<p>The Session can manage transactions automatically, including across multiple engines.  When the Session is in a transaction, as it receives requests to execute SQL statements, it adds each individual Connection/Engine encountered to its transactional state.  At commit time, all unflushed data is flushed, and each individual transaction is committed.  If the underlying databases support two-phase semantics, this may be used by the Session as well if two-phase transactions are enabled.
</p>
<p>The easiest way to use a Session with transactions is just to declare it as transactional.  The session will remain in a transaction at all times:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># transactional session
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">try</span><span class="python_operator">:
    </span><span class="python_name">item1 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">item2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">item1</span><span class="python_operator">.</span><span class="python_name">foo </span><span class="python_operator">= </span><span class="python_literal">'bar'</span><span class="python_operator">
    </span><span class="python_name">item2</span><span class="python_operator">.</span><span class="python_name">bar </span><span class="python_operator">= </span><span class="python_literal">'foo'</span><span class="python_operator">
</span>
    <span class="python_comment"># commit- will immediately go into a new transaction afterwards
    </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">except</span><span class="python_operator">:
    </span><span class="python_comment"># rollback - will immediately go into a new transaction afterwards.
</span><span class="python_operator">    </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Things to note above:
</p>
<ul>
 <li>
     When using a transactional session, either a <code>rollback()</code> or a <code>close()</code> call <strong>is required</strong> when an error is raised by <code>flush()</code> or <code>commit()</code>.  The <code>flush()</code> error condition will issue a ROLLBACK to the database automatically, but the state of the <code>Session</code> itself remains in an "undefined" state until the user decides whether to rollback or close.
 </li>

 <li>
     The <code>commit()</code> call unconditionally issues a <code>flush()</code>.  Particularly when using <code>transactional=True</code> in conjunction with <code>autoflush=True</code>, explicit <code>flush()</code> calls are usually not needed.
 </li>
</ul>
<p>Alternatively, a transaction can be begun explicitly using <code>begin()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># non transactional session
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">try</span><span class="python_operator">:
    </span><span class="python_name">item1 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">item2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">item1</span><span class="python_operator">.</span><span class="python_name">foo </span><span class="python_operator">= </span><span class="python_literal">'bar'</span><span class="python_operator">
    </span><span class="python_name">item2</span><span class="python_operator">.</span><span class="python_name">bar </span><span class="python_operator">= </span><span class="python_literal">'foo'</span><span class="python_operator">
    </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">except</span><span class="python_operator">:
    </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_keyword">raise</span><span class="python_operator">
</span></pre>
    </div>
<p>Like the <code>transactional</code> example, the same rules apply; an explicit <code>rollback()</code> or <code>close()</code> is required when an error occurs, and the <code>commit()</code> call issues a <code>flush()</code> as well.
</p>
<p>Session also supports Python 2.5's with statement so that the example above can be written as:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">with </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_name">item1 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">item2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">2</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">item1</span><span class="python_operator">.</span><span class="python_name">foo </span><span class="python_operator">= </span><span class="python_literal">'bar'</span><span class="python_operator">
    </span><span class="python_name">item2</span><span class="python_operator">.</span><span class="python_name">bar </span><span class="python_operator">= </span><span class="python_literal">'foo'</span><span class="python_operator">
</span></pre>
    </div>
<p>Subtransactions can be created by calling the <code>begin()</code> method repeatedly. For each transaction you <code>begin()</code> you must always call either <code>commit()</code> or <code>rollback()</code>. Note that this includes the implicit transaction created by the transactional session. When a subtransaction is created the current transaction of the session is set to that transaction. Commiting the subtransaction will return you to the next outer transaction. Rolling it back will also return you to the next outer transaction, but in addition it will roll back database state to the innermost transaction that supports rolling back to. Usually this means the root transaction, unless you use the nested transaction functionality via the <code>begin_nested()</code> method. MySQL and Postgres (and soon Oracle) support using "nested" transactions by creating SAVEPOINTs, :
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">u1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">u2</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">begin_nested</span><span class="python_enclosure">() </span><span class="python_comment"># establish a savepoint</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">u3</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()  </span><span class="python_comment"># rolls back u3, keeps u1 and u2</span><span class="python_operator">
</span>
<span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">() </span><span class="python_comment"># commits u1 and u2</span><span class="python_operator">
</span></pre>
    </div>
<p>Finally, for MySQL, Postgres, and soon Oracle as well, the session can be instructed to use two-phase commit semantics. This will coordinate the commiting of transactions across databases so that the transaction is either committed or rolled back in all databases. You can also <code>prepare()</code> the session for interacting with transactions not managed by SQLAlchemy. To use two phase transactions set the flag <code>twophase=True</code> on the session:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine1 </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://db1'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">engine2 </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://db2'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">twophase</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># bind User operations to engine 1, Account operations to engine 2
</span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">configure</span><span class="python_enclosure">(</span><span class="python_name">binds</span><span class="python_operator">=</span><span class="python_enclosure">{</span><span class="python_name">User</span><span class="python_operator">:</span><span class="python_name">engine1</span><span class="python_operator">, </span><span class="python_name">Account</span><span class="python_operator">:</span><span class="python_name">engine2</span><span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># .... work with accounts and users
</span>
<span class="python_comment"># commit.  session will issue a flush to all DBs, and a prepare step to all DBs,
# before committing both transactions
</span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Be aware that when a crash occurs in one of the databases while the the transactions are prepared you have to manually commit or rollback the prepared transactions in your database as appropriate.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_flushsql"></a>
    
    <div class="sectionL2">

    <h3>Embedding SQL Insert/Update Expressions into a Flush</h3>
    
    

<p>This feature allows the value of a database column to be set to a SQL expression instead of a literal value.  It's especially useful for atomic updates, calling stored procedures, etc.  All you do is assign an expression to an attribute:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">SomeClass</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">pass</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">SomeClass</span><span class="python_operator">, </span><span class="python_name">some_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">someobject </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">SomeClass</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">get</span><span class="python_enclosure">(</span><span class="python_number">5</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># set 'value' attribute to a SQL expression adding one
</span><span class="python_name">someobject</span><span class="python_operator">.</span><span class="python_name">value </span><span class="python_operator">= </span><span class="python_name">some_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">value </span><span class="python_operator">+ </span><span class="python_number">1</span><span class="python_operator">
</span>
<span class="python_comment"># issues "UPDATE some_table SET value=value+1"
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>This works both for INSERT and UPDATE statements.  After the flush/commit operation, the <code>value</code> attribute on <code>someobject</code> gets "deferred", so that when you again access it the newly generated value will be loaded from the database.  This is the same mechanism at work when database-side column defaults fire off.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_sql"></a>
    
    <div class="sectionL2">

    <h3>Using SQL Expressions with Sessions</h3>
    
    

<p>SQL constructs and string statements can be executed via the <code>Session</code>.  You'd want to do this normally when your <code>Session</code> is transactional and you'd like your free-standing SQL statements to participate in the same transaction.
</p>
<p>The two ways to do this are to use the connection/execution services of the Session, or to have your Session participate in a regular SQL transaction.
</p>
<p>First, a Session thats associated with an Engine or Connection can execute statements immediately (whether or not it's transactional):
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select * from table where id=:id"</span><span class="python_operator">, </span><span class="python_enclosure">{</span><span class="python_literal">'id'</span><span class="python_operator">:</span><span class="python_number">7</span><span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">result2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">mytable</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_number">7</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>To get at the current connection used by the session, which will be part of the current transaction if one is in progress, use <code>connection()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">connection</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>A second scenario is that of a Session which is not directly bound to a connectable.  This session executes statements relative to a particular <code>Mapper</code>, since the mappers are bound to tables which are in turn bound to connectables via their <code>MetaData</code> (either the session or the mapped tables need to be bound).  In this case, the Session can conceivably be associated with multiple databases through different mappers; so it wants you to send along a <code>mapper</code> argument, which can be any mapped class or mapper instance:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># session is *not* bound to an engine or connection
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># need to specify mapper or class when executing
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select * from table where id=:id"</span><span class="python_operator">, </span><span class="python_enclosure">{</span><span class="python_literal">'id'</span><span class="python_operator">:</span><span class="python_number">7</span><span class="python_enclosure">}</span><span class="python_operator">, </span><span class="python_name">mapper</span><span class="python_operator">=</span><span class="python_name">MyMappedClass</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">result2 </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">mytable</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_operator">==</span><span class="python_number">7</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">mapper</span><span class="python_operator">=</span><span class="python_name">MyMappedClass</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># need to specify mapper or class when you call connection()
</span><span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">connection</span><span class="python_enclosure">(</span><span class="python_name">MyMappedClass</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The third scenario is when you are using <code>Connection</code> and <code>Transaction</code> yourself, and want the <code>Session</code> to participate.  This is easy, as you just bind the <code>Session</code> to the connection:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># non-transactional session
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># non-ORM connection + transaction
</span><span class="python_name">conn </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">trans </span><span class="python_operator">= </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># bind the Session *instance* to the connection
</span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">conn</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># ... etc
</span>
<span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>It's safe to use a <code>Session</code> which is transactional or autoflushing, as well as to call <code>begin()</code>/<code>commit()</code> on the session too; the outermost Transaction object, the one we declared explicitly, controls the scope of the transaction.
</p>
<p>When using the <code>threadlocal</code> engine context, things are that much easier; the <code>Session</code> uses the same connection/transaction as everyone else in the current thread, whether or not you explicitly bind it:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://mydb'</span><span class="python_operator">, </span><span class="python_name">strategy</span><span class="python_operator">=</span><span class="python_literal">"threadlocal"</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()  </span><span class="python_comment"># session takes place in the transaction like everyone else</span><span class="python_operator">
</span>
<span class="python_comment"># ... go nuts
</span>
<span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">() </span><span class="python_comment"># commit the transaction</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_contextual"></a>
    
    <div class="sectionL2">

    <h3>Contextual/Thread-local Sessions</h3>
    
    

<p>A common need in applications, particularly those built around web frameworks, is the ability to "share" a <code>Session</code> object among disparate parts of an application, without needing to pass the object explicitly to all method and function calls.  What you're really looking for is some kind of "global" session object, or at least "global" to all the parts of an application which are tasked with servicing the current request.  For this pattern, SQLAlchemy provides the ability to enhance the <code>Session</code> class generated by <code>sessionmaker()</code> to provide auto-contextualizing support.  This means that whenever you create a <code>Session</code> instance with its constructor, you get an <em>existing</em> <code>Session</code> object which is bound to some "context".  By default, this context is the current thread.  This feature is what previously was accomplished using the <code>sessioncontext</code> SQLAlchemy extension.
</p>


    
    <A name="unitofwork_contextual_creating"></a>
    
    <div class="sectionL3">

    <h3>Creating a Thread-local Context</h3>
    
    

<p>The <code>scoped_session()</code> function wraps around the <code>sessionmaker()</code> function, and produces an object which behaves the same as the <code>Session</code> subclass returned by <code>sessionmaker()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm </span><span class="python_keyword">import </span><span class="python_name">scoped_session</span><span class="python_operator">, </span><span class="python_name">sessionmaker</span><span class="python_operator">
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">scoped_session</span><span class="python_enclosure">(</span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>However, when you instantiate this <code>Session</code> "class", in reality the object is pulled from a threadlocal variable, or if it doesn't exist yet, it's created using the underlying class generated by <code>sessionmaker()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># call Session() the first time.  the new Session instance is created.</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># later, in the same application thread, someone else calls Session()</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">sess2 </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_comment"># the two Session objects are *the same* object</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">sess </span><span class="python_keyword">is </span><span class="python_name">sess2</span><span class="python_operator">
</span><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>
<p>Since the <code>Session()</code> constructor now returns the same <code>Session</code> object every time within the current thread, the object returned by <code>scoped_session()</code> also implements most of the <code>Session</code> methods and properties at the "class" level, such that you don't even need to instantiate <code>Session()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># create some objects
</span><span class="python_name">u1 </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">u2 </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># save to the contextual session, without instantiating
</span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">u1</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">u2</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># view the "new" attribute
</span><span class="python_keyword">assert </span><span class="python_name">u1 </span><span class="python_keyword">in </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">new</span><span class="python_operator">
</span>
<span class="python_comment"># flush changes (if not using autoflush)
</span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">flush</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># commit transaction (if using a transactional session)
</span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>To "dispose" of the <code>Session</code>, there's two general approaches.  One is to close out the current session, but to leave it assigned to the current context.  This allows the same object to be re-used on another operation.  This may be called from a current, instantiated <code>Session</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">sess</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Or, when using <code>scoped_session()</code>, the <code>close()</code> method may also be called as a classmethod on the <code>Session</code> "class":
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>When the <code>Session</code> is closed, it remains attached, but clears all of its contents and releases any ongoing transactional resources, including rolling back any remaining transactional state.  The <code>Session</code> can then be used again.
</p>
<p>The other method is to remove the current session from the current context altogether.  This is accomplished using the classmethod <code>remove()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">remove</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>After <code>remove()</code>  is called, the next call to <code>Session()</code> will create a <em>new</em> <code>Session</code> object which then becomes the contextual session.
</p>
<p>That, in a nutshell, is all there really is to it.  Now for all the extra things one should know.
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_contextual_lifespan"></a>
    
    <div class="sectionL3">

    <h3>Lifespan of a Contextual Session</h3>
    
    

<p>A (really, really) common question is when does the contextual session get created, when does it get disposed ?  We'll consider a typical lifespan as used in a web application:
</p>

    

    <div class="sliding_code">
        <pre>
Web Server          Web Framework        User-defined Controller Call
--------------      --------------       ------------------------------
web request    -> 
                    call controller ->   # call Session().  this establishes a new,
                                         # contextual Session.
                                         sess = Session()

                                         # load some objects, save some changes
                                         objects = sess.query(MyClass).all()

                                         # some other code calls Session, it's the 
                                         # same contextual session as "sess"
                                         sess2 = Session()
                                         sess2.save(foo)
                                         sess2.commit()

                                         # generate content to be returned
                                         return generate_content()
                    Session.remove() <-
web response   <-
</pre>
    </div>
<p>Above, we illustrate a <em>typical</em> organization of duties, where the "Web Framework" layer has some integration built-in to manage the span of ORM sessions.  Upon the initial handling of an incoming web request, the framework passes control to a controller.  The controller then calls <code>Session()</code> when it wishes to work with the ORM; this method establishes the contextual Session which will remain until it's removed.  Disparate parts of the controller code may all call <code>Session()</code> and will get the same session object.  Then, when the controller has completed and the response is to be sent to the web server, the framework <strong>closes out</strong> the current contextual session, above using the <code>remove()</code> method which removes the session from the context altogether.
</p>
<p>As an alternative, the "finalization" step can also call <code>Session.close()</code>, which will leave the same session object in place.  Which one is better ?  For a web framework which runs from a fixed pool of threads, it doesn't matter much.  For a framework which runs a <strong>variable</strong> number of threads, or which <strong>creates and disposes</strong> of a thread for each request, <code>remove()</code> is better, since it leaves no resources associated with the thread which might not exist.
</p>
<ul>
 <li><p>Why close out the session at all ?  Why not just leave it going so the next request doesn't have to do as many queries ?
</p>
<p>There are some cases where you may actually want to do this.  However, this is a special case where you are dealing with data which <strong>does not change</strong> very often, or you don't care about the "freshness" of the data.  In reality, a single thread of a web server may, on a slow day, sit around for many minutes or even hours without being accessed.  When it's next accessed, if data from the previous request still exists in the session, that data may be very stale indeed.  So it's generally better to have an empty session at the start of a web request.
</p>

 </li>
</ul>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_contextual_associating"></a>
    
    <div class="sectionL3">

    <h3>Associating Classes and Mappers with a Contextual Session</h3>
    
    

<p>Another luxury we gain, when we've established a <code>Session()</code> that can be globally accessed, is the ability for mapped classes and objects to provide us with session-oriented functionality automatically.  When using the <code>scoped_session()</code> function, we access this feature using the <code>mapper</code> attribute on the object in place of the normal <code>sqlalchemy.orm.mapper</code> function:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># "contextual" mapper function
</span><span class="python_name">mapper </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">
</span>
<span class="python_comment"># use normally
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>When we use the contextual <code>mapper()</code> function, our <code>User</code> and <code>Address</code> now gain a new attribute <code>query</code>, which will create a <code>Query</code> object for us against the contextual session:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">wendy </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">filter_by</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'wendy'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">one</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>


    
    <A name="unitofwork_contextual_associating_autosave"></a>
    
    <div class="sectionL4">

    <h3>Auto-Save Behavior with Contextual Session's Mapper</h3>
    
    

<p>By default, when using Session.mapper, <strong>new instances are saved into the contextual session automatically upon construction;</strong> there is no longer a need to call <code>save()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">newuser </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">assert </span><span class="python_name">newuser </span><span class="python_keyword">in </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">new</span><span class="python_operator">
</span><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>
<p>The auto-save functionality can cause problems, namely that any <code>flush()</code> which occurs before a newly constructed object is fully populated will result in that object being INSERTed without all of its attributes completed.  As a <code>flush()</code> is more frequent when using sessions with <code>autoflush=True</code>, <strong>the auto-save behavior can be disabled</strong>, using the <code>save_on_init=False</code> flag:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># "contextual" mapper function
</span><span class="python_name">mapper </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">mapper</span><span class="python_operator">
</span>
<span class="python_comment"># use normally, specify no save on init:
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_enclosure">)</span>
<span class="python_enclosure">}</span><span class="python_operator">, </span><span class="python_name">save_on_init</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">addresses_table</span><span class="python_operator">, </span><span class="python_name">save_on_init</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># objects now again require explicit "save"
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">newuser </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">assert </span><span class="python_name">newuser </span><span class="python_keyword">in </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">new</span><span class="python_operator">
</span><span class="python_name">False</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">save</span><span class="python_enclosure">(</span><span class="python_name">newuser</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">assert </span><span class="python_name">newuser </span><span class="python_keyword">in </span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">new</span><span class="python_operator">
</span><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>
<p>The functionality of <code>Session.mapper</code> is an updated version of what used to be accomplished by the <code>assignmapper()</code> SQLAlchemy extension.
</p>
<p><a href="#docstrings_sqlalchemy.orm_modfunc_scoped_session">Generated docstrings for scoped_session()</a>
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>




    </div>




    </div>



    
    <A name="unitofwork_contextual_partitioning"></a>
    
    <div class="sectionL3">

    <h3>Partitioning Strategies</h3>
    
    

<p>this section is TODO
</p>


    
    <A name="unitofwork_contextual_partitioning_vertical"></a>
    
    <div class="sectionL4">

    <h3>Vertical Partitioning</h3>
    
    

<p>Vertical partitioning places different kinds of objects, or different tables, across multiple databases.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine1 </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://db1'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">engine2 </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://db2'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">twophase</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># bind User operations to engine 1, Account operations to engine 2
</span><span class="python_name">Session</span><span class="python_operator">.</span><span class="python_name">configure</span><span class="python_enclosure">(</span><span class="python_name">binds</span><span class="python_operator">=</span><span class="python_enclosure">{</span><span class="python_name">User</span><span class="python_operator">:</span><span class="python_name">engine1</span><span class="python_operator">, </span><span class="python_name">Account</span><span class="python_operator">:</span><span class="python_name">engine2</span><span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">Session</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>



    
    <A name="unitofwork_contextual_partitioning_horizontal"></a>
    
    <div class="sectionL4">

    <h3>Horizontal Partitioning</h3>
    
    

<p>Horizontal partitioning partitions the rows of a single table (or a set of tables) across multiple databases.
</p>
<p>See the "sharding" example in <a href='http://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/examples/sharding/attribute_shard.py'>attribute_shard.py</a>
</p>



            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="unitofwork_contextual_extending"></a>
    
    <div class="sectionL3">

    <h3>Extending Session</h3>
    
    

<p>Extending the session can be achieved through subclassing as well as through a simple extension class, which resembles the style of <a href="#advdatamapping_mapper_extending">Extending Mapper</a> called <a href="sqlalchemy_orm_session.html#docstrings_sqlalchemy.orm.session_SessionExtension">SessionExtension</a>.  See the docstrings for more information on this class' methods.
</p>
<p>Basic usage is similar to <code>MapperExtension</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MySessionExtension</span><span class="python_enclosure">(</span><span class="python_name">SessionExtension</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">before_commit</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">session</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">print </span><span class="python_literal">"before commit!"</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">extension</span><span class="python_operator">=</span><span class="python_name">MySessionExtension</span><span class="python_enclosure">())</span><span class="python_operator">
</span></pre>
    </div>
<p>or with <code>create_session()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">sess </span><span class="python_operator">= </span><span class="python_name">create_session</span><span class="python_enclosure">(</span><span class="python_name">extension</span><span class="python_operator">=</span><span class="python_name">MySessionExtension</span><span class="python_enclosure">())</span><span class="python_operator">
</span></pre>
    </div>
<p>The same <code>SessionExtension</code> instance can be used with any number of sessions.
</p>




            <a href="#unitofwork" class="totoc">back to section top</a>
    </div>




    </div>



    
    
    <A name="dbengine"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#unitofwork">Using the Session</a>

               |   
            Next: <a href="#metadata">Database Meta Data</a>
    </div>

        <h2>Database Engines</h2>
    </div>


        








    
    <A name="dbengine"></a>
    
    <div class="sectionL1">

    
    

<p>The <strong>Engine</strong> is the starting point for any SQLAlchemy application.  It's "home base" for the actual database and its DBAPI, delivered to the SQLAlchemy application through a connection pool and a <strong>Dialect</strong>, which describes how to talk to a specific kind of database and DBAPI combination.
</p>
<p>The general structure is this:
</p>

    

    <div class="sliding_code">
        <pre>
                                     +-----------+                        __________
                                 /---|   Pool    |---\                   (__________)
             +-------------+    /    +-----------+    \     +--------+   |          |
connect() <--|   Engine    |---x                       x----| DBAPI  |---| database |
             +-------------+    \    +-----------+    /     +--------+   |          |
                                 \---|  Dialect  |---/                   |__________|
                                     +-----------+                       (__________)
</pre>
    </div>
<p>Where above, a <a href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Engine">sqlalchemy.engine.Engine</a> references both a  <a href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Dialect">sqlalchemy.engine.Dialect</a> and <a href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool_Pool">sqlalchemy.pool.Pool</a>, which together interpret the DBAPI's module functions as well as the behavior of the database.
</p>
<p>Creating an engine is just a matter of issuing a single call, <code>create_engine()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://scott:tiger@localhost:5432/mydatabase'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The above engine invokes the <code>postgres</code> dialect and a connection pool which references <code>localhost:5432</code>.
</p>
<p>The engine can be used directly to issue SQL to the database.  The most generic way is to use connections, which you get via the <code>connect()</code> method:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select username from users"</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:
    </span><span class="python_keyword">print </span><span class="python_literal">"username:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_literal">'username'</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The connection is an instance of <a href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_Connection">sqlalchemy.engine.Connection</a>, which is a <strong>proxy</strong> object for an actual DBAPI connection.  The returned result is an instance of <a href="sqlalchemy_engine.html#docstrings_sqlalchemy.engine_ResultProxy">sqlalchemy.engine.ResultProxy</a>, which acts very much like a DBAPI cursor.
</p>
<p>When you say <code>engine.connect()</code>, a new <code>Connection</code> object is created, and a DBAPI connection is retrieved from the connection pool.  Later, when you call <code>connection.close()</code>, the DBAPI connection is returned to the pool; nothing is actually "closed" from the perspective of the database.
</p>
<p>To execute some SQL more quickly, you can skip the <code>Connection</code> part and just say:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select username from users"</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:
    </span><span class="python_keyword">print </span><span class="python_literal">"username:"</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_literal">'username'</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_name">result</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Where above, the <code>execute()</code> method on the <code>Engine</code> does the <code>connect()</code> part for you, and returns the <code>ResultProxy</code> directly.  The actual <code>Connection</code> is <em>inside</em> the <code>ResultProxy</code>, waiting for you to finish reading the result.  In this case, when you <code>close()</code> the <code>ResultProxy</code>, the underlying <code>Connection</code> is closed, which returns the DBAPI connection to the pool. 
</p>
<p>To summarize the above two examples, when you use a <code>Connection</code> object, it's known as <strong>explicit execution</strong>.  When you don't see the <code>Connection</code> object, but you still use the <code>execute()</code> method on the <code>Engine</code>, it's called <strong>explicit, connectionless execution</strong>.   A third variant of execution also exists called <strong>implicit execution</strong>; this will be described later.
</p>
<p>The <code>Engine</code> and <code>Connection</code> can do a lot more than what we illustrated above; SQL strings are only its most rudimentary function.  Later chapters will describe how "constructed SQL" expressions can be used with engines; in many cases, you don't have to deal with the <code>Engine</code> at all after it's created.  The Object Relational Mapper (ORM), an optional feature of SQLAlchemy, also uses the <code>Engine</code> in order to get at connections; that's also a case where you can often create the engine once, and then forget about it.
</p>


    
    <A name="dbengine_supported"></a>
    
    <div class="sectionL2">

    <h3>Supported Databases</h3>
    
    

<p>Recall that the <code>Dialect</code> is used to describe how to talk to a specific kind of database.  Dialects are included with SQLAlchemy for SQLite, Postgres, MySQL, MS-SQL, Firebird, Informix, and Oracle; these can each be seen as a Python module present in the <code>sqlalchemy.databases</code> package.  Each dialect requires the appropriate DBAPI drivers to be installed separately.
</p>
<p>Downloads for each DBAPI at the time of this writing are as follows:
</p>
<ul>
 <li>
     Postgres:  <a href='http://www.initd.org/tracker/psycopg/wiki/PsycopgTwo'>psycopg2</a>
 </li>

 <li>
     SQLite:  <a href='http://initd.org/tracker/pysqlite'>pysqlite</a>
 </li>

 <li>
     MySQL:   <a href='http://sourceforge.net/projects/mysql-python'>MySQLDB</a>
 </li>

 <li>
     Oracle:  <a href='http://www.cxtools.net/default.aspx?nav=home'>cx_Oracle</a>
 </li>

 <li>
     MS-SQL:  <a href='http://pyodbc.sourceforge.net/'>pyodbc</a> (recommended) <a href='http://adodbapi.sourceforge.net/'>adodbapi</a>  <a href='http://pymssql.sourceforge.net/'>pymssql</a>
 </li>

 <li>
     Firebird:  <a href='http://kinterbasdb.sourceforge.net/'>kinterbasdb</a>
 </li>

 <li>
     Informix:  <a href='http://informixdb.sourceforge.net/'>informixdb</a>
 </li>
</ul>
<p>The SQLAlchemy Wiki contains a page of database notes, describing whatever quirks and behaviors have been observed.  Its a good place to check for issues with specific databases.  <a href='http://www.sqlalchemy.org/trac/wiki/DatabaseNotes'>Database Notes</a>
</p>



            <a href="#dbengine" class="totoc">back to section top</a>
    </div>



    
    <A name="dbengine_establishing"></a>
    
    <div class="sectionL2">

    <h3>create_engine() URL Arguments</h3>
    
    

<p>SQLAlchemy indicates the source of an Engine strictly via <a href='http://rfc.net/rfc1738.html'>RFC-1738</a> style URLs, combined with optional keyword arguments to specify options for the Engine.  The form of the URL is:
</p>
<pre><code>driver://username:password@host:port/database
</code></pre><p>Available drivernames are <code>sqlite</code>, <code>mysql</code>, <code>postgres</code>, <code>oracle</code>, <code>mssql</code>, and <code>firebird</code>.  For sqlite, the database name is the filename to connect to, or the special name ":memory:" which indicates an in-memory database.  The URL is typically sent as a string to the <code>create_engine()</code> function:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># postgres
</span><span class="python_name">pg_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://scott:tiger@localhost:5432/mydatabase'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># sqlite (note the four slashes for an absolute path)
</span><span class="python_name">sqlite_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:////absolute/path/to/database.txt'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sqlite_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///relative/path/to/database.txt'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">sqlite_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite://'</span><span class="python_enclosure">)  </span><span class="python_comment"># in-memory database</span><span class="python_operator">
</span><span class="python_name">sqlite_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite://:memory:'</span><span class="python_enclosure">)  </span><span class="python_comment"># the same</span><span class="python_operator">
</span>
<span class="python_comment"># mysql
</span><span class="python_name">mysql_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'mysql://localhost/foo'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># oracle via TNS name
</span><span class="python_name">oracle_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'oracle://scott:tiger@dsn'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># oracle will feed host/port/SID into cx_oracle.makedsn
</span><span class="python_name">oracle_db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'oracle://scott:tiger@127.0.0.1:1521/sidname'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>Engine</code> will ask the connection pool for a connection when the <code>connect()</code> or <code>execute()</code> methods are called.  The default connection pool, <code>QueuePool</code>, as well as the default connection pool used with SQLite, <code>SingletonThreadPool</code>, will open connections to the database on an as-needed basis.  As concurrent statements are executed, <code>QueuePool</code> will grow its pool of connections to a default size of five, and will allow a default "overflow" of ten.   Since the <code>Engine</code> is essentially "home base" for the connection pool, it follows that you should keep a single <code>Engine</code> per database established within an application, rather than creating a new one for each connection.
</p>


    
    <A name="dbengine_establishing_custom"></a>
    
    <div class="sectionL3">

    <h3>Custom DBAPI connect() arguments</h3>
    
    

<p>Custom arguments used when issuing the <code>connect()</code> call to the underlying DBAPI may be issued in three distinct ways.  String-based arguments can be passed directly from the URL string as query arguments:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://scott:tiger@localhost/test?argument1=foo&amp;argument2=bar'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>If SQLAlchemy's database connector is aware of a particular query argument, it may convert its type from string to its proper type.
</p>
<p><code>create_engine</code> also takes an argument <code>connect_args</code> which is an additional dictionary that will be passed to <code>connect()</code>.  This can be used when arguments of a type other than string are required, and SQLAlchemy's database connector has no type conversion logic present for that parameter:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://scott:tiger@localhost/test'</span><span class="python_operator">, </span><span class="python_name">connect_args </span><span class="python_operator">= </span><span class="python_enclosure">{</span><span class="python_literal">'argument1'</span><span class="python_operator">:</span><span class="python_number">17</span><span class="python_operator">, </span><span class="python_literal">'argument2'</span><span class="python_operator">:</span><span class="python_literal">'bar'</span><span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>The most customizable connection method of all is to pass a <code>creator</code> argument, which specifies a callable that returns a DBAPI connection:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">def </span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_keyword">return </span><span class="python_name">psycopg</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">(</span><span class="python_name">user</span><span class="python_operator">=</span><span class="python_literal">'scott'</span><span class="python_operator">, </span><span class="python_name">host</span><span class="python_operator">=</span><span class="python_literal">'localhost'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://'</span><span class="python_operator">, </span><span class="python_name">creator</span><span class="python_operator">=</span><span class="python_name">connect</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#dbengine" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="dbengine_options"></a>
    
    <div class="sectionL2">

    <h3>Database Engine Options</h3>
    
    

<p>Keyword options can also be specified to <code>create_engine()</code>, following the string URL as follows:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://...'</span><span class="python_operator">, </span><span class="python_name">encoding</span><span class="python_operator">=</span><span class="python_literal">'latin1'</span><span class="python_operator">, </span><span class="python_name">echo</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>A list of all standard options, as well as several that are used by particular database dialects, is as follows:
</p>
<ul>
 <li>
     <strong>assert_unicode=False</strong> - When set to <code>True</code> alongside convert_unicode=<code>True</code>, asserts that incoming string bind parameters are instances of <code>unicode</code>, otherwise raises an error.  Only takes effect when <code>convert_unicode==True</code>.  This flag is also available on the <code>String</code> type and its descendants. New in 0.4.2.  <br></br>
 </li>

 <li>
     <strong>connect_args</strong> - a dictionary of options which will be passed directly to the DBAPI's <code>connect()</code> method as additional keyword arguments.
 </li>

 <li>
     <strong>convert_unicode=False</strong> - if set to True, all String/character based types will convert Unicode values to raw byte values going into the database, and all raw byte values to Python Unicode coming out in result sets.  This is an engine-wide method to provide unicode conversion across the board.  For unicode conversion on a column-by-column level, use the <code>Unicode</code> column type instead, described in <a href="#types">The Types System</a>.
 </li>

 <li>
     <strong>creator</strong> - a callable which returns a DBAPI connection.  This creation function will be passed to the underlying connection pool and will be used to create all new database connections.  Usage of this function causes connection parameters specified in the URL argument to be bypassed.
 </li>

 <li>
     <strong>echo=False</strong> - if True, the Engine will log all statements as well as a repr() of their parameter lists to the engines logger, which defaults to sys.stdout.  The <code>echo</code> attribute of <code>Engine</code> can be modified at any time to turn logging on and off.  If set to the string <code>&quot;debug&quot;</code>, result rows will be printed to the standard output as well.  This flag ultimately controls a Python logger; see <a href="#dbengine_logging">Configuring Logging</a> at the end of this chapter for information on how to configure logging directly.
 </li>

 <li>
     <strong>echo_pool=False</strong> - if True, the connection pool will log all checkouts/checkins to the logging stream, which defaults to sys.stdout.  This flag ultimately controls a Python logger; see <a href="#dbengine_logging">Configuring Logging</a> for information on how to configure logging directly.
 </li>

 <li>
     <strong>encoding='utf-8'</strong> - the encoding to use for all Unicode translations, both by engine-wide unicode conversion as well as the <code>Unicode</code> type object.
 </li>

 <li>
     <strong>module=None</strong> - used by database implementations which support multiple DBAPI modules, this is a reference to a DBAPI2 module to be used instead of the engine's default module.  For Postgres, the default is psycopg2.  For Oracle, it's cx_Oracle.
 </li>

 <li>
     <strong>pool=None</strong> - an already-constructed instance of <code>sqlalchemy.pool.Pool</code>, such as a <code>QueuePool</code> instance.  If non-None, this pool will be used directly as the underlying connection pool for the engine, bypassing whatever connection parameters are present in the URL argument.  For information on constructing connection pools manually, see <a href="#pooling">Connection Pooling</a>.
 </li>

 <li>
     <strong>poolclass=None</strong> - a <code>sqlalchemy.pool.Pool</code> subclass, which will be used to create a connection pool instance using the connection parameters given in the URL.  Note this differs from <code>pool</code> in that you don't actually instantiate the pool in this case, you just indicate what type of pool to be used.
 </li>

 <li>
     <strong>max_overflow=10</strong> - the number of connections to allow in connection pool "overflow", that is connections that can be opened above and beyond the pool_size setting, which defaults to five.  this is only used with <code>QueuePool</code>.
 </li>

 <li>
     <strong>pool_size=5</strong> - the number of connections to keep open inside the connection pool.  This used with <code>QueuePool</code> as well as <code>SingletonThreadPool</code>.
 </li>

 <li>
     <strong>pool_recycle=-1</strong> - this setting causes the pool to recycle connections after the given number of seconds has passed.  It defaults to -1, or no timeout.  For example, setting to 3600 means connections will be recycled after one hour.  Note that MySQL in particular will <strong>disconnect automatically</strong> if no activity is detected on a connection for eight hours (although this is configurable with the MySQLDB connection itself and the  server configuration as well).
 </li>

 <li>
     <strong>pool_timeout=30</strong> - number of seconds to wait before giving up on getting a connection from the pool.  This is only used with <code>QueuePool</code>.
 </li>

 <li>
     <strong>strategy='plain'</strong> - the Strategy argument is used to select alternate implementations of the underlying Engine object, which coordinates operations between dialects, compilers, connections, and so on.  Currently, the only alternate strategy besides the default value of "plain" is the "threadlocal" strategy, which selects the usage of the <code>TLEngine</code> class that provides a modified connection scope for connectionless executions.  Connectionless execution as well as further detail on this setting are described in <a href="#dbengine_implicit">Connectionless Execution, Implicit Execution</a>.
 </li>

 <li>
     <strong>threaded=True</strong> - used by cx_Oracle; sets the <code>threaded</code> parameter of the connection indicating thread-safe usage.  cx_Oracle docs indicate setting this flag to <code>False</code> will speed performance by 10-15%.  While this defaults to <code>False</code> in cx_Oracle, SQLAlchemy defaults it to <code>True</code>, preferring stability over early optimization.
 </li>

 <li>
     <strong>use_ansi=True</strong> - used only by Oracle;  when False, the Oracle driver attempts to support a particular "quirk" of Oracle versions 8 and previous, that the LEFT OUTER JOIN SQL syntax is not supported, and the "Oracle join" syntax of using <code>column1(+)=column2</code> must be used in order to achieve a LEFT OUTER JOIN.
 </li>

 <li>
     <strong>use_oids=False</strong> - used only by Postgres, will enable the column name "oid" as the object ID column, which is also used for the default sort order of tables.  Postgres as of 8.1 has object IDs disabled by default.
 </li>
</ul>



            <a href="#dbengine" class="totoc">back to section top</a>
    </div>



    
    <A name="dbengine_connections"></a>
    
    <div class="sectionL2">

    <h3>More On Connections</h3>
    
    

<p>Recall from the beginning of this section that the Engine provides a <code>connect()</code> method which returns a <code>Connection</code> object.  <code>Connection</code> is a <em>proxy</em> object which maintains a reference to a DBAPI connection instance.  The <code>close()</code> method on <code>Connection</code> does not actually close the DBAPI connection, but instead returns it to the connection pool referenced by the <code>Engine</code>.  <code>Connection</code> will also automatically return its resources to the connection pool when the object is garbage collected, i.e. its <code>__del__()</code> method is called.  When using the standard C implementation of Python, this method is usually called immediately as soon as the object is dereferenced.  With other Python implementations such as Jython, this is not so guaranteed.  <br></br>
</p>
<p>The <code>execute()</code> methods on both <code>Engine</code> and <code>Connection</code> can also receive SQL clause constructs as well:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">select</span><span class="python_enclosure">([</span><span class="python_name">table1</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">table1</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">col1</span><span class="python_operator">==</span><span class="python_number">5</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:
    </span><span class="python_keyword">print </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_literal">'col1'</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">row</span><span class="python_enclosure">[</span><span class="python_literal">'col2'</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The above SQL construct is known as a <code>select()</code>.  The full range of SQL constructs available are described in <a href="#sql">SQL Expression Language Tutorial</a>.
</p>
<p>Both <code>Connection</code> and <code>Engine</code> fulfill an interface known as <code>Connectable</code> which specifies common functionality between the two objects, namely being able to call <code>connect()</code> to return a <code>Connection</code> object (<code>Connection</code> just returns itself), and being able to call <code>execute()</code> to get a result set.   Following this, most SQLAlchemy functions and objects which accept an <code>Engine</code> as a parameter or attribute with which to execute SQL will also accept a <code>Connection</code>.  As of SQLAlchemy 0.3.9, this argument is named <code>bind</code>.
</p>

    

    <div class="sliding_code">
            <div class="codetitle">Specify Engine or Connection</div>
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///:memory:'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># specify some Table metadata
</span><span class="python_name">metadata </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'sometable'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col1'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_comment"># create the table with the Engine
</span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">create</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># drop the table with a Connection off the Engine
</span><span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">drop</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">connection</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Connection facts:
</p>
<ul>
 <li>
     the Connection object is <strong>not threadsafe</strong>.  While a Connection can be shared among threads using properly synchronized access, this is also not recommended as many DBAPIs have issues with, if not outright disallow, sharing of connection state between threads.
 </li>

 <li>
     The Connection object represents a single dbapi connection checked out from the connection pool.  In this state, the connection pool has no affect upon the connection, including its expiration or timeout state.  For the connection pool to properly manage connections, <em></em>connections should be returned to the connection pool (i.e. <code>connection.close()</code>) whenever the connection is not in use<em></em>.  If your application has a need for management of multiple connections or is otherwise long running (this includes all web applications, threaded or not), don't hold a single connection open at the module level.
 </li>
</ul>



            <a href="#dbengine" class="totoc">back to section top</a>
    </div>



    
    <A name="dbengine_transactions"></a>
    
    <div class="sectionL2">

    <h3>Using Transactions with Connection</h3>
    
    

<p>The <code>Connection</code> object provides a <code>begin()</code> method which returns a <code>Transaction</code> object.  This object is usually used within a try/except clause so that it is guaranteed to <code>rollback()</code> or <code>commit()</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">trans </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">try</span><span class="python_operator">:
    </span><span class="python_name">r1 </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">table1</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">())</span><span class="python_operator">
    </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">table1</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">()</span><span class="python_operator">, </span><span class="python_name">col1</span><span class="python_operator">=</span><span class="python_number">7</span><span class="python_operator">, </span><span class="python_name">col2</span><span class="python_operator">=</span><span class="python_literal">'this is some data'</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">except</span><span class="python_operator">:
    </span><span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_keyword">raise</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>Transaction</code> object also handles "nested" behavior by keeping track of the outermost begin/commit pair.  In this example, two functions both issue a transaction on a Connection, but only the outermost Transaction object actually takes effect when it is committed.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># method_a starts a transaction and calls method_b
</span><span class="python_keyword">def </span><span class="python_name">method_a</span><span class="python_enclosure">(</span><span class="python_name">connection</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">trans </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">() </span><span class="python_comment"># open a transaction</span><span class="python_operator">
    </span><span class="python_keyword">try</span><span class="python_operator">:
        </span><span class="python_name">method_b</span><span class="python_enclosure">(</span><span class="python_name">connection</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()  </span><span class="python_comment"># transaction is committed here</span><span class="python_operator">
    </span><span class="python_keyword">except</span><span class="python_operator">:
        </span><span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">() </span><span class="python_comment"># this rolls back the transaction unconditionally</span><span class="python_operator">
        </span><span class="python_keyword">raise</span><span class="python_operator">
</span>
<span class="python_comment"># method_b also starts a transaction
</span><span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">method_b</span><span class="python_enclosure">(</span><span class="python_name">connection</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">trans </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">() </span><span class="python_comment"># open a transaction - this runs in the context of method_a's transaction</span><span class="python_operator">
    </span><span class="python_keyword">try</span><span class="python_operator">:
        </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"insert into mytable values ('bat', 'lala')"</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">()</span><span class="python_operator">, </span><span class="python_name">col1</span><span class="python_operator">=</span><span class="python_literal">'bat'</span><span class="python_operator">, </span><span class="python_name">col2</span><span class="python_operator">=</span><span class="python_literal">'lala'</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()  </span><span class="python_comment"># transaction is not committed yet</span><span class="python_operator">
    </span><span class="python_keyword">except</span><span class="python_operator">:
        </span><span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">() </span><span class="python_comment"># this rolls back the transaction unconditionally</span><span class="python_operator">
        </span><span class="python_keyword">raise</span><span class="python_operator">
</span>
<span class="python_comment"># open a Connection and call method_a
</span><span class="python_operator"></span><span class="python_name">conn </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()                </span><span class="python_operator">
</span><span class="python_name">method_a</span><span class="python_enclosure">(</span><span class="python_name">conn</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, <code>method_a</code> is called first, which calls <code>connection.begin()</code>.  Then it calls <code>method_b</code>. When <code>method_b</code> calls <code>connection.begin()</code>, it just increments a counter that is decremented when it calls <code>commit()</code>.  If either <code>method_a</code> or <code>method_b</code> calls <code>rollback()</code>, the whole transaction is rolled back.  The transaction is not committed until <code>method_a</code> calls the <code>commit()</code> method.  This "nesting" behavior allows the creation of functions which "guarantee" that a transaction will be used if one was not already available, but will automatically participate in an enclosing transaction if one exists.
</p>
<p>Note that SQLAlchemy's Object Relational Mapper also provides a way to control transaction scope at a higher level; this is described in <b>unitofwork_transaction</b>.
</p>
<p>Transaction Facts:
</p>
<ul>
 <li>
     the Transaction object, just like its parent Connection, is <strong>not threadsafe</strong>.
 </li>

 <li>
     SQLAlchemy 0.4 will feature transactions with two-phase commit capability as well as SAVEPOINT capability.
 </li>
</ul>


    
    <A name="dbengine_transactions_understanding"></a>
    
    <div class="sectionL3">

    <h3>Understanding Autocommit</h3>
    
    

<p>The above transaction example illustrates how to use <code>Transaction</code> so that several executions can take part in the same transaction.  What happens when we issue an INSERT, UPDATE or DELETE call without using <code>Transaction</code>?  The answer is <strong>autocommit</strong>.  While many DBAPIs  implement a flag called <code>autocommit</code>, the current SQLAlchemy behavior is such that it implements its own autocommit.  This is achieved by searching the statement for strings like INSERT, UPDATE, DELETE, etc. and then issuing a COMMIT automatically if no transaction is in progress.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">conn </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"INSERT INTO users VALUES (1, 'john')"</span><span class="python_enclosure">)  </span><span class="python_comment"># autocommits</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#dbengine" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="dbengine_implicit"></a>
    
    <div class="sectionL2">

    <h3>Connectionless Execution, Implicit Execution</h3>
    
    

<p>Recall from the first section we mentioned executing with and without a <code>Connection</code>.  <code>Connectionless</code> execution refers to calling the <code>execute()</code> method on an object which is not a <code>Connection</code>, which could be on the <code>Engine</code> itself, or could be a constructed SQL object.  When we say "implicit", we mean that we are calling the <code>execute()</code> method on an object which is neither a <code>Connection</code> nor an <code>Engine</code> object; this can only be used with constructed SQL objects which have their own <code>execute()</code> method, and can be "bound" to an <code>Engine</code>.  A description of "constructed SQL objects" may be found in <a href="#sql">SQL Expression Language Tutorial</a>.
</p>
<p>A summary of all three methods follows below.  First, assume the usage of the following <code>MetaData</code> and <code>Table</code> objects; while we haven't yet introduced these concepts, for now you only need to know that we are representing a database table, and are creating an "executable" SQL construct which issues a statement to the database.  These objects are described in <a href="#metadata">Database Meta Data</a>.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">users_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Explicit execution delivers the SQL text or constructed SQL expression to the <code>execute()</code> method of <code>Connection</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///file.db'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">())</span><span class="python_operator">
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:
    </span><span class="python_comment"># ....
</span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Explicit, connectionless execution delivers the expression to the <code>execute()</code> method of <code>Engine</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///file.db'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">())</span><span class="python_operator">
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:
    </span><span class="python_comment"># ....
</span><span class="python_name">result</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Implicit execution is also connectionless, and calls the <code>execute()</code> method on the expression itself, utilizing the fact that either an <code>Engine</code> or <code>Connection</code> has been <em>bound</em> to the expression object (binding is discussed further in the next section, <a href="#metadata">Database Meta Data</a>):
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///file.db'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">result</span><span class="python_operator">:
    </span><span class="python_comment"># ....
</span><span class="python_name">result</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>In both "connectionless" examples, the <code>Connection</code> is created behind the scenes; the <code>ResultProxy</code> returned by the <code>execute()</code> call references the <code>Connection</code> used to issue the SQL statement.   When we issue <code>close()</code> on the <code>ResultProxy</code>, or if the result set object falls out of scope and is garbage collected, the underlying <code>Connection</code> is closed for us, resulting in the DBAPI connection being returned to the pool.
</p>


    
    <A name="dbengine_implicit_strategies"></a>
    
    <div class="sectionL3">

    <h3>Using the Threadlocal Execution Strategy</h3>
    
    

<p>With connectionless execution, each returned <code>ResultProxy</code> object references its own distinct DBAPI connection object.  This means that multiple executions will result in multiple DBAPI connections being used at the same time; the example below illustrates this:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'mysql://localhost/test'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># execute one statement and receive results.  r1 now references a DBAPI connection resource.
</span><span class="python_name">r1 </span><span class="python_operator">= </span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select * from table1"</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># execute a second statement and receive results.  r2 now references a *second* DBAPI connection resource.
</span><span class="python_name">r2 </span><span class="python_operator">= </span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select * from table2"</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">r1</span><span class="python_operator">:
    ...
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">r2</span><span class="python_operator">:
    ...
</span><span class="python_comment"># release connection 1
</span><span class="python_operator"></span><span class="python_name">r1</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># release connection 2
</span><span class="python_name">r2</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Where above, we have two result sets in scope at the same time, therefore we have two distinct DBAPI connections, both separately checked out from the connection pool, in scope at the same time.
</p>
<p>An option exists to <code>create_engine()</code> called <code>strategy=&quot;threadlocal&quot;</code>, which changes this behavior.  When this option is used, the <code>Engine</code> which is returned by <code>create_engine()</code> is a special subclass of engine called <code>TLEngine</code>.  This engine, when it creates the <code>Connection</code> used by a connectionless execution, checks a <strong>threadlocal variable</strong> for an existing DBAPI connection that was already checked out from the pool, within the current thread.  If one exists, it uses that one. 
</p>
<p>The usage of "threadlocal" modifies the underlying behavior of our example above, as follows:
</p>

    

    <div class="sliding_code">
            <div class="codetitle">Threadlocal Strategy</div>
        <pre>
<span class="python_name">db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'mysql://localhost/test'</span><span class="python_operator">, </span><span class="python_name">strategy</span><span class="python_operator">=</span><span class="python_literal">'threadlocal'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># execute one statement and receive results.  r1 now references a DBAPI connection resource.
</span><span class="python_name">r1 </span><span class="python_operator">= </span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select * from table1"</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># execute a second statement and receive results.  r2 now references the *same* resource as r1
</span><span class="python_name">r2 </span><span class="python_operator">= </span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"select * from table2"</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">r1</span><span class="python_operator">:
    ...
</span><span class="python_keyword">for </span><span class="python_name">row </span><span class="python_keyword">in </span><span class="python_name">r2</span><span class="python_operator">:
    ...
</span><span class="python_comment"># close r1.  the connection is still held by r2.
</span><span class="python_operator"></span><span class="python_name">r1</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># close r2.  with no more references to the underlying connection resources, they
# are returned to the pool.
</span><span class="python_name">r2</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Where above, we again have two result sets in scope at the same time, but because they are present in the same thread, there is only <strong>one DBAPI connection in use</strong>.
</p>
<p>While the above distinction may not seem like much, it has several potentially desirable effects.  One is that you can in some cases reduce the number of concurrent connections checked out from the connection pool, in the case that a <code>ResultProxy</code> is still opened and a second statement is issued.  A second advantage is that by limiting the number of checked out connections in a thread to just one, you eliminate the issue of deadlocks within a single thread, such as when connection A locks a table, and connection B attempts to read from the same table in the same thread, it will "deadlock" on waiting for connection A to release its lock; the <code>threadlocal</code> strategy eliminates this possibility.
</p>
<p>A third advantage to the <code>threadlocal</code> strategy is that it allows the <code>Transaction</code> object to be used in combination with connectionless execution.  Recall from the section on transactions, that the <code>Transaction</code> is returned by the <code>begin()</code> method on a <code>Connection</code>; all statements which wish to participate in this transaction must be executed by the same <code>Connection</code>, thereby forcing the usage of an explicit connection.  However, the <code>TLEngine</code> provides a <code>Transaction</code> that is local to the current thread;  using it, one can issue many "connectionless" statements within a thread and they will all automatically partake in the current transaction, as in the example below:
</p>

    

    <div class="sliding_code">
            <div class="codetitle">threadlocal connection sharing</div>
        <pre>
<span class="python_comment"># get a TLEngine
</span><span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'mysql://localhost/test'</span><span class="python_operator">, </span><span class="python_name">strategy</span><span class="python_operator">=</span><span class="python_literal">'threadlocal'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">try</span><span class="python_operator">:
    </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"insert into users values (?, ?)"</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">"john"</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">update</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_number">5</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">except</span><span class="python_operator">:
    </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Notice that no <code>Connection</code> needed to be used; the <code>begin()</code> method on <code>TLEngine</code> (which note is not available on the regular <code>Engine</code>) created a <code>Transaction</code> as well as a <code>Connection</code>, and held onto both in a context corresponding to the current thread.  Each <code>execute()</code> call made use of the same connection, allowing them all to participate in the same transaction.
</p>
<p>Complex application flows can take advantage of the "threadlocal" strategy in order to allow many disparate parts of an application to take place in the same transaction automatically.  The example below demonstrates several forms of "connectionless execution" as well as some specialized explicit ones:
</p>

    

    <div class="sliding_code">
            <div class="codetitle">threadlocal connection sharing</div>
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'mysql://localhost/test'</span><span class="python_operator">, </span><span class="python_name">strategy</span><span class="python_operator">=</span><span class="python_literal">'threadlocal'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">def </span><span class="python_name">dosomethingimplicit</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_name">table1</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"some sql"</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">table1</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"some other sql"</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">dosomethingelse</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_name">table2</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"some sql"</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">conn </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">contextual_connect</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_comment"># do stuff with conn
    </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"some other sql"</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">close</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">dosomethingtransactional</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_name">conn </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">contextual_connect</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_name">trans </span><span class="python_operator">= </span><span class="python_name">conn</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
     </span><span class="python_comment"># do stuff
    </span><span class="python_name">trans</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">try</span><span class="python_operator">:
    </span><span class="python_name">dosomethingimplicit</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_name">dosomethingelse</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_name">dosomethingtransactional</span><span class="python_enclosure">()</span><span class="python_operator">
    </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">commit</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_keyword">except</span><span class="python_operator">:
    </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>In the above example, the program calls three functions <code>dosomethingimplicit()</code>, <code>dosomethingelse()</code> and <code>dosomethingtransactional()</code>.  All three functions use either connectionless execution, or a special function <code>contextual_connect()</code> which we will describe in a moment.  These two styles of execution both indicate that all executions will use the same connection object.  Additionally, the method <code>dosomethingtransactional()</code> begins and commits its own <code>Transaction</code>.  But only one transaction is used, too; it's controlled completely by the <code>engine.begin()</code>/<code>engine.commit()</code> calls at the bottom.  Recall that <code>Transaction</code> supports "nesting" behavior, whereby transactions begun on a <code>Connection</code> which already has a transaction open, will "nest" into the enclosing transaction.  Since the transaction opened in <code>dosomethingtransactional()</code> occurs using the same connection which already has a transaction begun, it "nests" into that transaction and therefore has no effect on the actual transaction scope (unless it calls <code>rollback()</code>).
</p>
<p>Some of the functions in the above example make use of a method called <code>engine.contextual_connect()</code>.  This method is available on both <code>Engine</code> as well as <code>TLEngine</code>, and returns the <code>Connection</code> that applies to the current <strong>connection context</strong>.  When using the <code>TLEngine</code>, this is just another term for the "thread local connection" that is being used for all connectionless executions.  When using just the regular <code>Engine</code> (i.e. the "default" strategy), <code>contextual_connect()</code> is synonymous with <code>connect()</code>.  Below we illustrate that two connections opened via <code>contextual_connect()</code> at the same time, both reference the same underlying DBAPI connection:
</p>

    

    <div class="sliding_code">
            <div class="codetitle">Contextual Connection</div>
        <pre>
<span class="python_comment"># threadlocal strategy
</span><span class="python_name">db </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'mysql://localhost/test'</span><span class="python_operator">, </span><span class="python_name">strategy</span><span class="python_operator">=</span><span class="python_literal">'threadlocal'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">conn1 </span><span class="python_operator">= </span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">contextual_connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">conn2 </span><span class="python_operator">= </span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">contextual_connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">conn1</span><span class="python_operator">.</span><span class="python_name">connection </span><span class="python_keyword">is </span><span class="python_name">conn2</span><span class="python_operator">.</span><span class="python_name">connection</span><span class="python_operator">
</span><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>
<p>The basic idea of <code>contextual_connect()</code> is that it's the "connection used by connectionless execution".  It's different from the <code>connect()</code> method in that <code>connect()</code> is always used when handling an explicit <code>Connection</code>, which will always reference distinct DBAPI connection.  Using <code>connect()</code> in combination with <code>TLEngine</code> allows one to "circumvent" the current thread local context, as in this example where a single statement issues data to the database externally to the current transaction:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">begin</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"insert into users values (?, ?)"</span><span class="python_operator">, </span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_literal">"john"</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">update</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_number">5</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">rollback</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>In the above example, a thread-local transaction is begun, but is later rolled back.  The statement <code>insert into users values (?, ?)</code> is executed without using a connection, therefore uses the thread-local transaction.  So its data is rolled back when the transaction is rolled back.  However, the <code>users.update()</code> statement is executed using a distinct <code>Connection</code> returned by the <code>engine.connect()</code> method, so it therefore is not part of the threadlocal transaction; it autocommits immediately.
</p>



            <a href="#dbengine" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="dbengine_logging"></a>
    
    <div class="sectionL2">

    <h3>Configuring Logging</h3>
    
    

<p>As of the 0.3 series of SQLAlchemy, Python's standard <a href='http://www.python.org/doc/lib/module-logging.html'>logging</a> module is used to implement informational and debug log output.  This allows SQLAlchemy's logging to integrate in a standard way with other applications and libraries.  The <code>echo</code> and <code>echo_pool</code> flags that are present on <code>create_engine()</code>, as well as the <code>echo_uow</code> flag used on <code>Session</code>, all interact with regular loggers.
</p>
<p>This section assumes familiarity with the above linked logging module.  All logging performed by SQLAlchemy exists underneath the <code>sqlalchemy</code> namespace, as used by <code>logging.getLogger('sqlalchemy')</code>.  When logging has been configured (i.e. such as via <code>logging.basicConfig()</code>), the general namespace of SA loggers that can be turned on is as follows:
</p>
<ul>
 <li>
     <code>sqlalchemy.engine</code> - controls SQL echoing.  set to <code>logging.INFO</code> for SQL query output, <code>logging.DEBUG</code> for query + result set output.
 </li>

 <li>
     <code>sqlalchemy.pool</code> - controls connection pool logging.  set to <code>logging.INFO</code> or lower to log connection pool checkouts/checkins.
 </li>

 <li>
     <code>sqlalchemy.orm</code> - controls logging of various ORM functions.  set to <code>logging.INFO</code> for configurational logging as well as unit of work dumps, <code>logging.DEBUG</code> for extensive logging during query and flush() operations.  Subcategories of <code>sqlalchemy.orm</code> include:<ul>
 <li>
     <code>sqlalchemy.orm.attributes</code> - logs certain instrumented attribute operations, such as triggered callables
 </li>

 <li>
     <code>sqlalchemy.orm.mapper</code> - logs Mapper configuration and operations
 </li>

 <li>
     <code>sqlalchemy.orm.unitofwork</code> - logs flush() operations, including dependency sort graphs and other operations
 </li>

 <li>
     <code>sqlalchemy.orm.strategies</code> - logs relation loader operations (i.e. lazy and eager loads)
 </li>

 <li>
     <code>sqlalchemy.orm.sync</code> - logs synchronization of attributes from parent to child instances during a flush()
 </li>
</ul>

 </li>
</ul>
<p>For example, to log SQL queries as well as unit of work debugging:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">import </span><span class="python_name">logging</span><span class="python_operator">
</span>
<span class="python_name">logging</span><span class="python_operator">.</span><span class="python_name">basicConfig</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">logging</span><span class="python_operator">.</span><span class="python_name">getLogger</span><span class="python_enclosure">(</span><span class="python_literal">'sqlalchemy.engine'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">setLevel</span><span class="python_enclosure">(</span><span class="python_name">logging</span><span class="python_operator">.</span><span class="python_name">INFO</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">logging</span><span class="python_operator">.</span><span class="python_name">getLogger</span><span class="python_enclosure">(</span><span class="python_literal">'sqlalchemy.orm.unitofwork'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">setLevel</span><span class="python_enclosure">(</span><span class="python_name">logging</span><span class="python_operator">.</span><span class="python_name">DEBUG</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>By default, the log level is set to <code>logging.ERROR</code> within the entire <code>sqlalchemy</code> namespace so that no log operations occur, even within an application that has logging enabled otherwise.
</p>
<p>The <code>echo</code> flags present as keyword arguments to <code>create_engine()</code> and others as well as the <code>echo</code> property on <code>Engine</code>, when set to <code>True</code>, will first attempt to ensure that logging is enabled.  Unfortunately, the <code>logging</code> module provides no way of determining if output has already been configured (note we are referring to if a logging configuration has been set up, not just that the logging level is set).  For this reason, any <code>echo=True</code> flags will result in a call to <code>logging.basicConfig()</code> using sys.stdout as the destination.  It also sets up a default format using the level name, timestamp, and logger name.  Note that this configuration has the affect of being configured <strong>in addition</strong> to any existing logger configurations.  Therefore, <strong>when using Python logging, ensure all echo flags are set to False at all times</strong>, to avoid getting duplicate log lines.
</p>




            <a href="#dbengine" class="totoc">back to section top</a>
    </div>




    </div>



    
    
    <A name="metadata"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#dbengine">Database Engines</a>

               |   
            Next: <a href="#types">The Types System</a>
    </div>

        <h2>Database Meta Data</h2>
    </div>


        








    
    <A name="metadata"></a>
    
    <div class="sectionL1">

    
    



    
    <A name="metadata_tables"></a>
    
    <div class="sectionL2">

    <h3>Describing Databases with MetaData</h3>
    
    

<p>The core of SQLAlchemy's query and object mapping operations are supported by <strong>database metadata</strong>, which is comprised of Python objects that describe tables and other schema-level objects.  These objects can be created by explicitly naming the various components and their properties, using the Table, Column, ForeignKey, Index, and Sequence objects imported from <code>sqlalchemy.schema</code>.  There is also support for <strong>reflection</strong> of some entities, which means you only specify the <em>name</em> of the entities and they are recreated from the database automatically.
</p>
<p>A collection of metadata entities is stored in an object aptly named <code>MetaData</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy </span><span class="python_keyword">import </span><span class="python_operator">*
</span>
<span class="python_name">metadata </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>To represent a Table, use the <code>Table</code> class:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">users </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key </span><span class="python_operator">= </span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">16</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable </span><span class="python_operator">= </span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email_address'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">60</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">key</span><span class="python_operator">=</span><span class="python_literal">'email'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'password'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">20</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable </span><span class="python_operator">= </span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">user_prefs </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'user_prefs'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'pref_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"users.user_id"</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'pref_name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">40</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'pref_value'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The specific datatypes for each Column, such as Integer, String, etc. are described in <a href="#types">The Types System</a>, and exist within the module <code>sqlalchemy.types</code> as well as the global <code>sqlalchemy</code> namespace.
</p>
<p>Foreign keys are most easily specified by the <code>ForeignKey</code> object within a <code>Column</code> object.  For a composite foreign key, i.e. a foreign key that contains multiple columns referencing multiple columns to a composite primary key, an explicit syntax is provided which allows the correct table CREATE statements to be generated:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># a table with a composite primary key
</span><span class="python_name">invoices </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'invoices'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'invoice_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'ref_num'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'description'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">60</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># a table with a composite foreign key referencing the parent table
</span><span class="python_name">invoice_items </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'invoice_items'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'item_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'item_name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">60</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'invoice_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'ref_num'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">ForeignKeyConstraint</span><span class="python_enclosure">([</span><span class="python_literal">'invoice_id'</span><span class="python_operator">, </span><span class="python_literal">'ref_num'</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_enclosure">[</span><span class="python_literal">'invoices.invoice_id'</span><span class="python_operator">, </span><span class="python_literal">'invoices.ref_num'</span><span class="python_enclosure">])</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, the <code>invoice_items</code> table will have <code>ForeignKey</code> objects automatically added to the <code>invoice_id</code> and <code>ref_num</code> <code>Column</code> objects as a result of the additional <code>ForeignKeyConstraint</code> object.
</p>
<p>The <code>MetaData</code> object supports some handy methods, such as getting a list of Tables in the order (or reverse) of their dependency:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">for </span><span class="python_name">t </span><span class="python_keyword">in </span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">table_iterator</span><span class="python_enclosure">(</span><span class="python_name">reverse</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">:
...    </span><span class="python_keyword">print </span><span class="python_name">t</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">
</span><span class="python_name">users</span><span class="python_operator">
</span><span class="python_name">user_prefs</span><span class="python_operator">
</span></pre>
    </div>
<p>And <code>Table</code> provides an interface to the table's properties as well as that of its columns:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">employees </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">60</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_operator">, </span><span class="python_name">key</span><span class="python_operator">=</span><span class="python_literal">'name'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_dept'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"departments.department_id"</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># access the column "EMPLOYEE_ID":
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">columns</span><span class="python_operator">.</span><span class="python_name">employee_id</span><span class="python_operator">
</span>
<span class="python_comment"># or just
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_id</span><span class="python_operator">
</span>
<span class="python_comment"># via string
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_enclosure">[</span><span class="python_literal">'employee_id'</span><span class="python_enclosure">]</span><span class="python_operator">
</span>
<span class="python_comment"># iterate through all columns
</span><span class="python_keyword">for </span><span class="python_name">c </span><span class="python_keyword">in </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">:
    </span><span class="python_comment"># ...
</span>
<span class="python_comment"># get the table's primary key columns
</span><span class="python_keyword">for </span><span class="python_name">primary_key </span><span class="python_keyword">in </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">primary_key</span><span class="python_operator">:
    </span><span class="python_comment"># ...
</span>
<span class="python_comment"># get the table's foreign key objects:
</span><span class="python_keyword">for </span><span class="python_name">fkey </span><span class="python_keyword">in </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">foreign_keys</span><span class="python_operator">:
    </span><span class="python_comment"># ...
</span>
<span class="python_comment"># access the table's MetaData:
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">metadata</span><span class="python_operator">
</span>
<span class="python_comment"># access the table's bound Engine or Connection, if its MetaData is bound:
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">bind</span><span class="python_operator">
</span>
<span class="python_comment"># access a column's name, type, nullable, primary key, foreign key
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_id</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_id</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_id</span><span class="python_operator">.</span><span class="python_name">nullable</span><span class="python_operator">
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_id</span><span class="python_operator">.</span><span class="python_name">primary_key</span><span class="python_operator">
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_dept</span><span class="python_operator">.</span><span class="python_name">foreign_key</span><span class="python_operator">
</span>
<span class="python_comment"># get the "key" of a column, which defaults to its name, but can 
# be any user-defined string:
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">key</span><span class="python_operator">
</span>
<span class="python_comment"># access a column's table:
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_id</span><span class="python_operator">.</span><span class="python_name">table </span><span class="python_keyword">is </span><span class="python_name">employees</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">True</span><span class="python_operator">
</span>
<span class="python_comment"># get the table related by a foreign key
</span><span class="python_name">fcolumn </span><span class="python_operator">= </span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">employee_dept</span><span class="python_operator">.</span><span class="python_name">foreign_key</span><span class="python_operator">.</span><span class="python_name">column</span><span class="python_operator">.</span><span class="python_name">table</span><span class="python_operator">
</span></pre>
    </div>


    
    <A name="metadata_tables_binding"></a>
    
    <div class="sectionL3">

    <h3>Binding MetaData to an Engine or Connection</h3>
    
    

<p>A <code>MetaData</code> object can be associated with an <code>Engine</code> or an individual <code>Connection</code>; this process is called <strong>binding</strong>.  The term used to describe "an engine or a connection" is often referred to as a <strong>connectable</strong>.  Binding allows the <code>MetaData</code> and the elements which it contains to perform operations against the database directly, using the connection resources to which it's bound.   Common operations which are made more convenient through binding include being able to generate SQL constructs which know how to execute themselves, creating <code>Table</code> objects which query the database for their column and constraint information, and issuing CREATE or DROP statements.
</p>
<p>To bind <code>MetaData</code> to an <code>Engine</code>, use the <code>bind</code> attribute:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite://'</span><span class="python_operator">, **</span><span class="python_name">kwargs</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># create MetaData 
</span><span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># bind to an engine
</span><span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">
</span></pre>
    </div>
<p>Once this is done, the <code>MetaData</code> and its contained <code>Table</code> objects can access the database directly:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">()  </span><span class="python_comment"># issue CREATE statements for all tables</span><span class="python_operator">
</span>
<span class="python_comment"># describe a table called 'users', query the database for its columns
</span><span class="python_name">users_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span><span class="python_name">autoload</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># generate a SELECT statement and execute
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that the feature of binding engines is <strong>completely optional</strong>.  All of the operations which take advantage of "bound" <code>MetaData</code> also can be given an <code>Engine</code> or <code>Connection</code> explicitly with which to perform the operation.   The equivalent "non-bound" of the above would be:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_enclosure">)  </span><span class="python_comment"># issue CREATE statements for all tables</span><span class="python_operator">
</span>
<span class="python_comment"># describe a table called 'users',  query the database for its columns
</span><span class="python_name">users_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span><span class="python_name">autoload</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">autoload_with</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># generate a SELECT statement and execute
</span><span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">engine</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">())</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_tables_reflecting"></a>
    
    <div class="sectionL3">

    <h3>Reflecting Tables</h3>
    
    

<p>A <code>Table</code> object can be created without specifying any of its contained attributes, using the argument <code>autoload=True</code> in conjunction with the table's name and possibly its schema (if not the databases "default" schema).  (You can also specify a list or set of column names to autoload as the kwarg include_columns, if you only want to load a subset of the columns in the actual database.)  This will issue the appropriate queries to the database in order to locate all properties of the table required for SQLAlchemy to use it effectively, including its column names and datatypes, foreign and primary key constraints, and in some cases its default-value generating attributes.   To use <code>autoload=True</code>, the table's <code>MetaData</code> object need be bound to an <code>Engine</code> or <code>Connection</code>, or alternatively the <code>autoload_with=&lt;some connectable&gt;</code> argument can be passed.  Below we illustrate autoloading a table and then iterating through the names of its columns:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">messages </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'messages'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span><span class="python_name">autoload</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_enclosure">[</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_keyword">for </span><span class="python_name">c </span><span class="python_keyword">in </span><span class="python_name">messages</span><span class="python_operator">.</span><span class="python_name">columns</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_literal">'message_id'</span><span class="python_operator">, </span><span class="python_literal">'message_name'</span><span class="python_operator">, </span><span class="python_literal">'date'</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that if a reflected table has a foreign key referencing another table, the related <code>Table</code> object  will be automatically created within the <code>MetaData</code> object if it does not exist already.  Below, suppose table <code>shopping_cart_items</code> references a table <code>shopping_carts</code>.  After reflecting, the <code>shopping carts</code> table is present:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">shopping_cart_items </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'shopping_cart_items'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span><span class="python_name">autoload</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; 'shopping_carts' </span><span class="python_keyword">in </span><span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">tables</span><span class="python_operator">:
</span><span class="python_name">True</span><span class="python_operator">
</span></pre>
    </div>
<p>To get direct access to 'shopping_carts', simply instantiate it via the <code>Table</code> constructor.  <code>Table</code> uses a special contructor that will return the already created <code>Table</code> instance if it's already present:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">shopping_carts </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'shopping_carts'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Of course, it's a good idea to use <code>autoload=True</code> with the above table regardless.  This is so that if it hadn't been loaded already, the operation will load the table.  The autoload operation only occurs for the table if it hasn't already been loaded; once loaded, new calls to <code>Table</code> will not re-issue any reflection queries.
</p>

    
    <A name="metadata_tables_reflecting_overriding"></a>
    
    <div class="sectionL4">

    <h3>Overriding Reflected Columns</h3>
    
    
<p>Individual columns can be overridden with explicit values when reflecting tables; this is handy for specifying custom datatypes, constraints such as primary keys that may not be configured within the database, etc.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">mytable </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'mytable'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
<span class="python_operator">... </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,   </span><span class="python_comment"># override reflected 'id' to have primary key</span>
<span class="python_operator">... </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'mydata'</span><span class="python_operator">, </span><span class="python_name">Unicode</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">,    </span><span class="python_comment"># override reflected 'mydata' to be Unicode</span>
<span class="python_operator">... </span><span class="python_name">autoload</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="metadata_tables_schema"></a>
    
    <div class="sectionL3">

    <h3>Specifying the Schema Name</h3>
    
    

<p>Some databases support the concept of multiple schemas.  A <code>Table</code> can reference this by specifying the <code>schema</code> keyword argument:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">financial_info </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'financial_info'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'value'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">schema</span><span class="python_operator">=</span><span class="python_literal">'remote_banks'</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Within the <code>MetaData</code> collection, this table will be identified by the combination of <code>financial_info</code> and <code>remote_banks</code>.  If another table called <code>financial_info</code> is referenced without the <code>remote_banks</code> schema, it will refer to a different <code>Table</code>.  <code>ForeignKey</code> objects can reference columns in this table using the form <code>remote_banks.financial_info.id</code>.
</p>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_tables_onupdate"></a>
    
    <div class="sectionL3">

    <h3>ON UPDATE and ON DELETE</h3>
    
    

<p><code>ON UPDATE</code> and <code>ON DELETE</code> clauses to a table create are specified within the <code>ForeignKeyConstraint</code> object, using the <code>onupdate</code> and <code>ondelete</code> keyword arguments:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">foobar </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'foobar'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'lala'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">40</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">ForeignKeyConstraint</span><span class="python_enclosure">([</span><span class="python_literal">'lala'</span><span class="python_enclosure">]</span><span class="python_operator">,</span><span class="python_enclosure">[</span><span class="python_literal">'hoho.lala'</span><span class="python_enclosure">]</span><span class="python_operator">, </span><span class="python_name">onupdate</span><span class="python_operator">=</span><span class="python_literal">"CASCADE"</span><span class="python_operator">, </span><span class="python_name">ondelete</span><span class="python_operator">=</span><span class="python_literal">"CASCADE"</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that these clauses are not supported on SQLite, and require <code>InnoDB</code> tables when used with MySQL.  They may also not be supported on other databases.
</p>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_tables_options"></a>
    
    <div class="sectionL3">

    <h3>Other Options</h3>
    
    

<p><code>Tables</code> may support database-specific options, such as MySQL's <code>engine</code> option that can specify "MyISAM", "InnoDB", and other backends for the table:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">addresses </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'engine_email_addresses'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'address_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key </span><span class="python_operator">= </span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'remote_user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email_address'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">20</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">mysql_engine</span><span class="python_operator">=</span><span class="python_literal">'InnoDB'</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="metadata_creating"></a>
    
    <div class="sectionL2">

    <h3>Creating and Dropping Database Tables</h3>
    
    

<p>Creating and dropping individual tables can be done via the <code>create()</code> and <code>drop()</code> methods of <code>Table</code>; these methods take an optional <code>bind</code> parameter which references an <code>Engine</code> or a <code>Connection</code>.  If not supplied, the <code>Engine</code> bound to the <code>MetaData</code> will be used, else an error is raised:
</p>

    

    <div class="code">
        <pre>
<span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">meta</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_literal">'sqlite:///:memory:'</span><span class="python_operator">
</span>
<span class="python_name">employees </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'employees'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">60</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_operator">, </span><span class="python_name">key</span><span class="python_operator">=</span><span class="python_literal">'name'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'employee_dept'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"departments.department_id"</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal"><a href="javascript:togglePopbox('popbox_98', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">create</span><span class="python_enclosure">()</span><span class="python_operator"></span></pre><div id="popbox_98_div" class="codepop" style="display:none;">CREATE TABLE employees(<br/>
employee_id SERIAL NOT NULL PRIMARY KEY,<br/>
employee_name VARCHAR(60) NOT NULL,<br/>
employee_dept INTEGER REFERENCES departments(department_id)<br/>
)<br/>
{}</div><pre><span class="python_operator"></span></pre>
    </div>
<p><code>drop()</code> method:
</p>

    

    <div class="code">
        <pre>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_99', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">drop</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">e</span><span class="python_enclosure">)</span><span class="python_operator"></span></pre><div id="popbox_99_div" class="codepop" style="display:none;">DROP TABLE employees<br/>
{}</div><pre><span class="python_operator"></span></pre>
    </div>
<p>The <code>create()</code> and <code>drop()</code> methods also support an optional keyword argument <code>checkfirst</code> which will issue the database's appropriate pragma statements to check if the table exists before creating or dropping:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">create</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">e</span><span class="python_operator">, </span><span class="python_name">checkfirst</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">employees</span><span class="python_operator">.</span><span class="python_name">drop</span><span class="python_enclosure">(</span><span class="python_name">checkfirst</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Entire groups of Tables can be created and dropped directly from the <code>MetaData</code> object with <code>create_all()</code> and <code>drop_all()</code>.  These methods always check for the existence of each table before creating or dropping.  Each method takes an optional <code>bind</code> keyword argument which can reference an <code>Engine</code> or a <code>Connection</code>.  If no engine is specified, the underlying bound <code>Engine</code>,  if any, is used:
</p>

    

    <div class="code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///:memory:'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">metadata </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_name">users </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key </span><span class="python_operator">= </span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">16</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable </span><span class="python_operator">= </span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email_address'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">60</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">key</span><span class="python_operator">=</span><span class="python_literal">'email'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'password'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">20</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable </span><span class="python_operator">= </span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">user_prefs </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'user_prefs'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'pref_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"users.user_id"</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'pref_name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">40</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'pref_value'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal"><a href="javascript:togglePopbox('popbox_100', 'show', 'hide')" class="codepoplink">sql</a></span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator"></span></pre><div id="popbox_100_div" class="codepop" style="display:none;">PRAGMA table_info(users){}<br/>
CREATE TABLE users(<br/>
        user_id INTEGER NOT NULL PRIMARY KEY, <br/>
        user_name VARCHAR(16) NOT NULL, <br/>
        email_address VARCHAR(60), <br/>
        password VARCHAR(20) NOT NULL<br/>
)<br/>
PRAGMA table_info(user_prefs){}<br/>
CREATE TABLE user_prefs(<br/>
        pref_id INTEGER NOT NULL PRIMARY KEY, <br/>
        user_id INTEGER NOT NULL REFERENCES users(user_id), <br/>
        pref_name VARCHAR(40) NOT NULL, <br/>
        pref_value VARCHAR(100)<br/>
)</div><pre><span class="python_operator"></span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_defaults"></a>
    
    <div class="sectionL2">

    <h3>Column Insert/Update Defaults</h3>
    
    

<p>SQLAlchemy includes several constructs which provide default values provided during INSERT and UPDATE statements.  The defaults may be provided as Python constants, Python functions, or SQL expressions, and the SQL expressions themselves may be "pre-executed", executed inline within the insert/update statement itself, or can be created as a SQL level "default" placed on the table definition itself.  A "default" value by definition is only invoked if no explicit value is passed into the INSERT or UPDATE statement.
</p>


    
    <A name="metadata_defaults_preexecute_functions"></a>
    
    <div class="sectionL3">

    <h3>Pre-Executed Python Functions</h3>
    
    

<p>The "default" keyword argument on Column can reference a Python value or callable which is invoked at the time of an insert:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># a function which counts upwards
</span><span class="python_name">i </span><span class="python_operator">= </span><span class="python_number">0</span><span class="python_operator">
</span><span class="python_keyword">def </span><span class="python_name">mydefault</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_keyword">global </span><span class="python_name">i</span><span class="python_operator">
    </span><span class="python_name">i </span><span class="python_operator">+= </span><span class="python_number">1</span><span class="python_operator">
    </span><span class="python_keyword">return </span><span class="python_name">i</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">t </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">"mytable"</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span>
    <span class="python_comment"># function-based default</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">default</span><span class="python_operator">=</span><span class="python_name">mydefault</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_comment"># a scalar default</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'key'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">10</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">default</span><span class="python_operator">=</span><span class="python_literal">"default"</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Similarly, the "onupdate" keyword does the same thing for update statements:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">import </span><span class="python_name">datetime</span><span class="python_operator">
</span>
<span class="python_name">t </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">"mytable"</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_comment"># define 'last_updated' to be populated with datetime.now()</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'last_updated'</span><span class="python_operator">, </span><span class="python_name">DateTime</span><span class="python_operator">, </span><span class="python_name">onupdate</span><span class="python_operator">=</span><span class="python_name">datetime</span><span class="python_operator">.</span><span class="python_name">now</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_defaults_sqlexpression"></a>
    
    <div class="sectionL3">

    <h3>Pre-executed and Inline SQL Expressions</h3>
    
    

<p>The "default" and "onupdate" keywords may also be passed SQL expressions, including select statements or direct function calls:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">t </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">"mytable"</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_comment"># define 'create_date' to default to now()</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'create_date'</span><span class="python_operator">, </span><span class="python_name">DateTime</span><span class="python_operator">, </span><span class="python_name">default</span><span class="python_operator">=</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">now</span><span class="python_enclosure">())</span><span class="python_operator">,</span>

    <span class="python_comment"># define 'key' to pull its default from the 'keyvalues' table</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'key'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">20</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">default</span><span class="python_operator">=</span><span class="python_name">keyvalues</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">keyvalues</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">type</span><span class="python_operator">=</span><span class="python_literal">'type1'</span><span class="python_operator">, </span><span class="python_name">limit</span><span class="python_operator">=</span><span class="python_number">1</span><span class="python_enclosure">))</span>

    <span class="python_comment"># define 'last_modified' to use the current_timestamp SQL function on update</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'last_modified'</span><span class="python_operator">, </span><span class="python_name">DateTime</span><span class="python_operator">, </span><span class="python_name">onupdate</span><span class="python_operator">=</span><span class="python_name">func</span><span class="python_operator">.</span><span class="python_name">current_timestamp</span><span class="python_enclosure">())</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The above SQL functions are usually executed "inline" with the INSERT or UPDATE statement being executed.  In some cases, the function is "pre-executed" and its result pre-fetched explicitly.  This happens under the following circumstances:
</p>
<ul>
 <li><p>the column is a primary key column
</p>

 </li>

 <li><p>the database dialect does not support a usable <code>cursor.lastrowid</code> accessor (or equivalent); this currently includes Postgres, Oracle, and Firebird.
</p>

 </li>

 <li><p>the statement is a single execution, i.e. only supplies one set of parameters and doesn't use "executemany" behavior
</p>

 </li>

 <li><p>the <code>inline=True</code> flag is not set on the <code>Insert()</code> or <code>Update()</code> construct.
</p>

 </li>
</ul>
<p>For a statement execution which is not an executemany, the returned <code>ResultProxy</code> will contain a collection accessible via <code>result.postfetch_cols()</code> which contains a list of all <code>Column</code> objects which had an inline-executed default.  Similarly, all parameters which were bound to the statement, including all Python and SQL expressions which were pre-executed, are present in the <code>last_inserted_params()</code> or <code>last_updated_params()</code> collections on <code>ResultProxy</code>.  The <code>last_inserted_ids()</code> collection contains a list of primary key values for the row inserted.  <br></br>
</p>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_defaults_passive"></a>
    
    <div class="sectionL3">

    <h3>DDL-Level Defaults</h3>
    
    

<p>A variant on a SQL expression default is the <code>PassiveDefault</code>, which gets placed in the CREATE TABLE statement during a <code>create()</code> operation:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">t </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'test'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'mycolumn'</span><span class="python_operator">, </span><span class="python_name">DateTime</span><span class="python_operator">, </span><span class="python_name">PassiveDefault</span><span class="python_enclosure">(</span><span class="python_name">text</span><span class="python_enclosure">(</span><span class="python_literal">"sysdate"</span><span class="python_enclosure">)))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>A create call for the above table will produce:
</p>

    

    <div class="sliding_code">
        <pre>
CREATE TABLE test (
    mycolumn datetime default sysdate
)
</pre>
    </div>
<p>The behavior of <code>PassiveDefault</code> is similar to that of a regular SQL default; if it's placed on a primary key column for a database which doesn't have a way to "postfetch" the ID, and the statement is not "inlined", the SQL expression is pre-executed; otherwise, SQLAlchemy lets the default fire off on the database side normally.
</p>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_defaults_sequences"></a>
    
    <div class="sectionL3">

    <h3>Defining Sequences</h3>
    
    

<p>A table with a sequence looks like:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">"cartitems"</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">, </span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">"cart_id"</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">Sequence</span><span class="python_enclosure">(</span><span class="python_literal">'cart_id_seq'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">"description"</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">40</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">"createdate"</span><span class="python_operator">, </span><span class="python_name">DateTime</span><span class="python_enclosure">())</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>Sequence</code> object works a lot like the <code>default</code> keyword on <code>Column</code>, except that it only takes effect on a database which supports sequences.  When used with a database that does not support sequences, the <code>Sequence</code> object has no effect; therefore it's safe to place on a table which is used against multiple database backends.  The same rules for pre- and inline execution apply.
</p>
<p>When the <code>Sequence</code> is associated with a table, CREATE and DROP statements issued for that table will also issue CREATE/DROP for the sequence object as well, thus "bundling" the sequence object with its parent table.
</p>
<p>The flag <code>optional=True</code> on <code>Sequence</code> will produce a sequence that is only used on databases which have no "autoincrementing" capability.  For example, Postgres supports primary key generation using the SERIAL keyword, whereas Oracle has no such capability.  Therefore, a <code>Sequence</code> placed on a primary key column with <code>optional=True</code> will only be used with an Oracle backend but not Postgres.
</p>
<p>A sequence can also be executed standalone, using an <code>Engine</code> or <code>Connection</code>, returning its next value in a database-independent fashion:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">seq </span><span class="python_operator">= </span><span class="python_name">Sequence</span><span class="python_enclosure">(</span><span class="python_literal">'some_sequence'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">nextid </span><span class="python_operator">= </span><span class="python_name">connection</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_name">seq</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="metadata_constraints"></a>
    
    <div class="sectionL2">

    <h3>Defining Constraints and Indexes</h3>
    
    



    
    <A name="metadata_constraints_unique"></a>
    
    <div class="sectionL3">

    <h3>UNIQUE Constraint</h3>
    
    

<p>Unique constraints can be created anonymously on a single column using the <code>unique</code> keyword on <code>Column</code>.  Explicitly named unique constraints and/or those with multiple columns are created via the <code>UniqueConstraint</code> table-level construct.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">mytable </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'mytable'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>

    <span class="python_comment"># per-column anonymous unique constraint</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col1'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">unique</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col2'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col3'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_comment"># explicit/composite unique constraint.  'name' is optional.</span>
    <span class="python_name">UniqueConstraint</span><span class="python_enclosure">(</span><span class="python_literal">'col2'</span><span class="python_operator">, </span><span class="python_literal">'col3'</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'uix_1'</span><span class="python_enclosure">)</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_constraints_check"></a>
    
    <div class="sectionL3">

    <h3>CHECK Constraint</h3>
    
    

<p>Check constraints can be named or unnamed and can be created at the Column or Table level, using the <code>CheckConstraint</code> construct.  The text of the check constraint is passed directly through to the database, so there is limited "database independent" behavior.  Column level check constraints generally should only refer to the column to which they are placed, while table level constraints can refer to any columns in the table.
</p>
<p>Note that some databases do not actively support check constraints such as MySQL and SQLite.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">mytable </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'mytable'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>

    <span class="python_comment"># per-column CHECK constraint</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col1'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">CheckConstraint</span><span class="python_enclosure">(</span><span class="python_literal">'col1&gt;5'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>

    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col2'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col3'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_comment"># table level CHECK constraint.  'name' is optional.</span>
    <span class="python_name">CheckConstraint</span><span class="python_enclosure">(</span><span class="python_literal">'col2 &gt; col3 + 5'</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'check1'</span><span class="python_enclosure">)</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>



    
    <A name="metadata_constraints_indexes"></a>
    
    <div class="sectionL3">

    <h3>Indexes</h3>
    
    

<p>Indexes can be created anonymously (using an auto-generated name "ix_<column label>") for a single column using the inline <code>index</code> keyword on <code>Column</code>, which also modifies the usage of <code>unique</code> to apply the uniqueness to the index itself, instead of adding a separate UNIQUE constraint.  For indexes with specific names or which encompass more than one column, use the <code>Index</code> construct, which requires a name.  <br></br>
</p>
<p>Note that the <code>Index</code> construct is created <strong>externally</strong> to the table which it corresponds, using <code>Column</code> objects and not strings.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">meta </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">mytable </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'mytable'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_comment"># an indexed column, with index "ix_mytable_col1"</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col1'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">index</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_comment"># a uniquely indexed column with index "ix_mytable_col2"</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col2'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">index</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">unique</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col3'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col4'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>

    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col5'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'col6'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># place an index on col3, col4
</span><span class="python_name">Index</span><span class="python_enclosure">(</span><span class="python_literal">'idx_col34'</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">col3</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">col4</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># place a unique index on col5, col6
</span><span class="python_name">Index</span><span class="python_enclosure">(</span><span class="python_literal">'myindex'</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">col5</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">col6</span><span class="python_operator">, </span><span class="python_name">unique</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>Index</code> objects will be created along with the CREATE statements for the table itself.  An index can also be created on its own independently of the table:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># create a table
</span><span class="python_name">sometable</span><span class="python_operator">.</span><span class="python_name">create</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># define an index
</span><span class="python_name">i </span><span class="python_operator">= </span><span class="python_name">Index</span><span class="python_enclosure">(</span><span class="python_literal">'someindex'</span><span class="python_operator">, </span><span class="python_name">sometable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">col5</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># create the index, will use the table's bound connectable if the `bind` keyword argument not specified
</span><span class="python_name">i</span><span class="python_operator">.</span><span class="python_name">create</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#metadata" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="metadata_adapting"></a>
    
    <div class="sectionL2">

    <h3>Adapting Tables to Alternate Metadata</h3>
    
    

<p>A <code>Table</code> object created against a specific <code>MetaData</code> object can be re-created against a new MetaData using the <code>tometadata</code> method:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_comment"># create two metadata
</span><span class="python_name">meta1 </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///querytest.db'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">meta2 </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># load 'users' from the sqlite engine
</span><span class="python_name">users_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">meta1</span><span class="python_operator">, </span><span class="python_name">autoload</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># create the same Table object for the plain metadata
</span><span class="python_name">users_table_2 </span><span class="python_operator">= </span><span class="python_name">users_table</span><span class="python_operator">.</span><span class="python_name">tometadata</span><span class="python_enclosure">(</span><span class="python_name">meta2</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>




            <a href="#metadata" class="totoc">back to section top</a>
    </div>




    </div>



    
    
    <A name="types"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#metadata">Database Meta Data</a>

               |   
            Next: <a href="#pooling">Connection Pooling</a>
    </div>

        <h2>The Types System</h2>
    </div>


        








    
    <A name="types"></a>
    
    <div class="sectionL1">

    
    

<p>The package <code>sqlalchemy.types</code> defines the datatype identifiers which may be used when defining <b>metadata</b>.  This package includes a set of generic types, a set of SQL-specific subclasses of those types, and a small extension system used by specific database connectors to adapt these generic types into database-specific type objects.
</p>


    
    <A name="types_standard"></a>
    
    <div class="sectionL2">

    <h3>Built-in Types</h3>
    
    

<p>SQLAlchemy comes with a set of standard generic datatypes, which are defined as classes.  Types are usually used when defining tables, and can be left as a class or instantiated, for example:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mytable </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'mytable'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'myid'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'data'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">30</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'info'</span><span class="python_operator">, </span><span class="python_name">Unicode</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'value'</span><span class="python_operator">, </span><span class="python_name">Number</span><span class="python_enclosure">(</span><span class="python_number">7</span><span class="python_operator">,</span><span class="python_number">4</span><span class="python_enclosure">)) </span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Following is a rundown of the standard types.
</p>


    
    <A name="types_standard_string"></a>
    
    <div class="sectionL3">

    <h3>String</h3>
    
    

<p>This type is the base type for all string and character types, such as <code>Unicode</code>, <code>TEXT</code>, <code>CLOB</code>, etc.  By default it generates a VARCHAR in DDL.  It includes an argument <code>length</code>, which indicates the length in characters of the type, as well as <code>convert_unicode</code> and <code>assert_unicode</code>, which are booleans.  <code>length</code> will be used as the length argument when generating DDL.  If <code>length</code> is omitted, the <code>String</code> type resolves into the <code>TEXT</code> type.
</p>
<p><code>convert_unicode=True</code> indicates that incoming strings, if they are Python <code>unicode</code> strings, will be encoded into a raw bytestring using the <code>encoding</code> attribute of the dialect (defaults to <code>utf-8</code>).  Similarly, raw bytestrings coming back from the database will be decoded into <code>unicode</code> objects on the way back.
</p>
<p><code>assert_unicode</code> is set to <code>None</code> by default. When <code>True</code>, it indicates that incoming bind parameters will be checked that they are in fact  <code>unicode</code> objects, else an error is raised.  A value of <code>'warn'</code> instead raises a warning.  Setting it to <code>None</code> indicates that the dialect-level <code>convert_unicode</code> setting should take place, whereas setting it to <code>False</code> disables it unconditionally  (this flag is new as of version 0.4.2).
</p>
<p>Both <code>convert_unicode</code> and <code>assert_unicode</code> may be set at the engine level as flags to <code>create_engine()</code>.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_unicode"></a>
    
    <div class="sectionL3">

    <h3>Unicode</h3>
    
    

<p>The <code>Unicode</code> type is shorthand for <code>String</code> with <code>convert_unicode=True</code> and <code>assert_unicode='warn'</code>.  When writing a Unicode-aware application, it is strongly recommended that this type is used, and that only Unicode strings are used in the application.  By "Unicode string" we mean a string with a u, i.e. <code>u'hello'</code>.  Otherwise, particularly when using the ORM, data will be converted to Unicode when it returns from the database, but local data which was generated locally will not be in Unicode format, which can create confusion.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_text"></a>
    
    <div class="sectionL3">

    <h3>Text / UnicodeText</h3>
    
    

<p>These are the "unbounded" versions of <code>String</code> and <code>Unicode</code>.  They have no "length" parameter, and generate a column type of TEXT or CLOB.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_numeric"></a>
    
    <div class="sectionL3">

    <h3>Numeric</h3>
    
    

<p>Numeric types return <code>decimal.Decimal</code> objects by default.  The flag <code>asdecimal=False</code> may be specified which enables the type to pass data straight through.   Numeric also takes "precision" and "scale" arguments which are used when CREATE TABLE is issued.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_float"></a>
    
    <div class="sectionL3">

    <h3>Float</h3>
    
    

<p>Float types return Python floats.  Float also takes a "precision" argument which is used when CREATE TABLE is issued.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_datetime/date/time"></a>
    
    <div class="sectionL3">

    <h3>Datetime/Date/Time</h3>
    
    

<p>Date and time types return objects from the Python <code>datetime</code> module.  Most DBAPIs have built in support for the datetime module, with the noted exception of SQLite.  In the case of SQLite, date and time types are stored as strings which are then converted back to datetime objects when rows are returned.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_interval"></a>
    
    <div class="sectionL3">

    <h3>Interval</h3>
    
    

<p>The Interval type deals with <code>datetime.timedelta</code> objects.  In Postgres, the native INTERVAL type is used; for others, the value is stored as a date which is relative to the "epoch" (Jan. 1, 1970).
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_binary"></a>
    
    <div class="sectionL3">

    <h3>Binary</h3>
    
    

<p>The Binary type generates BLOB or BYTEA when tables are created, and also converts incoming values using the <code>Binary</code> callable provided by each DBAPI.  <br></br>
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_boolean"></a>
    
    <div class="sectionL3">

    <h3>Boolean</h3>
    
    

<p>Boolean typically uses BOOLEAN or SMALLINT on the CREATE TABLE side, and returns Python <code>True</code> or <code>False</code>.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_pickletype"></a>
    
    <div class="sectionL3">

    <h3>PickleType</h3>
    
    

<p>PickleType builds upon the Binary type to apply Python's <code>pickle.dumps()</code> to incoming objects, and <code>pickle.loads()</code> on the way out, allowing any pickleable Python object to be stored as a serialized binary field.
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_standard_sqlspecific"></a>
    
    <div class="sectionL3">

    <h3>SQL-Specific Types</h3>
    
    

<p>These are subclasses of the generic types and include:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">FLOAT</span><span class="python_enclosure">(</span><span class="python_name">Numeric</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">TEXT</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">DECIMAL</span><span class="python_enclosure">(</span><span class="python_name">Numeric</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">INT</span><span class="python_enclosure">(</span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">INTEGER </span><span class="python_operator">= </span><span class="python_name">INT</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">TIMESTAMP</span><span class="python_enclosure">(</span><span class="python_name">DateTime</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">DATETIME</span><span class="python_enclosure">(</span><span class="python_name">DateTime</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">CLOB</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">VARCHAR</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">CHAR</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">BLOB</span><span class="python_enclosure">(</span><span class="python_name">Binary</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">class </span><span class="python_name">BOOLEAN</span><span class="python_enclosure">(</span><span class="python_name">Boolean</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The idea behind the SQL-specific types is that a CREATE TABLE statement would generate the exact type specified.  <br></br>
</p>



            <a href="#types" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="types_dialect"></a>
    
    <div class="sectionL2">

    <h3>Dialect Specific Types</h3>
    
    

<p>Each dialect has its own set of types, many of which are available only within that dialect.  For example, MySQL has a <code>BigInteger</code> type and Postgres has an <code>Inet</code> type.  To use these, import them from the module explicitly:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">databases</span><span class="python_operator">.</span><span class="python_name">mysql </span><span class="python_keyword">import </span><span class="python_name">MSEnum</span><span class="python_operator">, </span><span class="python_name">MSBigInteger</span><span class="python_operator">
</span>
<span class="python_name">table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'foo'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'enumerates'</span><span class="python_operator">, </span><span class="python_name">MSEnum</span><span class="python_enclosure">(</span><span class="python_literal">'a'</span><span class="python_operator">, </span><span class="python_literal">'b'</span><span class="python_operator">, </span><span class="python_literal">'c'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">MSBigInteger</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Or some postgres types:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">databases</span><span class="python_operator">.</span><span class="python_name">postgres </span><span class="python_keyword">import </span><span class="python_name">PGInet</span><span class="python_operator">, </span><span class="python_name">PGArray</span><span class="python_operator">
</span>
<span class="python_name">table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'foo'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'ipaddress'</span><span class="python_operator">, </span><span class="python_name">PGInet</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'elements'</span><span class="python_operator">, </span><span class="python_name">PGArray</span><span class="python_enclosure">(</span><span class="python_name">str</span><span class="python_enclosure">))   </span><span class="python_comment"># PGArray is available in 0.4, and takes a type argument</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#types" class="totoc">back to section top</a>
    </div>



    
    <A name="types_custom"></a>
    
    <div class="sectionL2">

    <h3>Creating your Own Types</h3>
    
    

<p>User-defined types can be created which can augment the bind parameter and result processing capabilities of the built in types.  This is usually achieved using the <code>TypeDecorator</code> class, which "decorates" the behavior of any existing type.  As of version 0.4.2, the new <code>process_bind_param()</code> and <code>process_result_value()</code> methods should be used:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">types </span><span class="python_keyword">as </span><span class="python_name">types</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">MyType</span><span class="python_enclosure">(</span><span class="python_name">types</span><span class="python_operator">.</span><span class="python_name">TypeDecorator</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_literal">"""a type that decorates Unicode, prefixes values with "PREFIX:" on 
    the way in and strips it off on the way out."""</span><span class="python_operator">
</span>
    <span class="python_name">impl </span><span class="python_operator">= </span><span class="python_name">types</span><span class="python_operator">.</span><span class="python_name">Unicode</span><span class="python_operator">
</span>
    <span class="python_keyword">def </span><span class="python_name">process_bind_param</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">value</span><span class="python_operator">, </span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_literal">"PREFIX:" </span><span class="python_operator">+ </span><span class="python_name">value</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">process_result_value</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">value</span><span class="python_operator">, </span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">value</span><span class="python_enclosure">[</span><span class="python_number">7</span><span class="python_operator">:</span><span class="python_enclosure">]</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">copy</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">MyType</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">impl</span><span class="python_operator">.</span><span class="python_name">length</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that the "old" way to process bind parameters and result values, the <code>convert_bind_param()</code> and <code>convert_result_value()</code> methods, are still available.  The downside of these is that when using a type which already processes data such as the <code>Unicode</code> type, you need to call the superclass version of these methods directly.  Using <code>process_bind_param()</code> and <code>process_result_value()</code>, user-defined code can return and receive the desired Python data directly.
</p>
<p>As of version 0.4.2, <code>TypeDecorator</code> should generally be used for any user-defined type which redefines the behavior of another type, including other <code>TypeDecorator</code> subclasses such as <code>PickleType</code>, and the new <code>process_...()</code> methods described above should be used.  <br></br>
</p>
<p>To build a type object from scratch, which will not have a corresponding database-specific implementation, subclass <code>TypeEngine</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">types </span><span class="python_keyword">as </span><span class="python_name">types</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">MyType</span><span class="python_enclosure">(</span><span class="python_name">types</span><span class="python_operator">.</span><span class="python_name">TypeEngine</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">precision </span><span class="python_operator">= </span><span class="python_number">8</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">precision </span><span class="python_operator">= </span><span class="python_name">precision</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">get_col_spec</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_literal">"MYTYPE(%s)" </span><span class="python_operator">% </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">precision</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">convert_bind_param</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">value</span><span class="python_operator">, </span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">value</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">convert_result_value</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">value</span><span class="python_operator">, </span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">value</span><span class="python_operator">
</span></pre>
    </div>
<p>Once you make your type, it's immediately useable:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'foo'</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'data'</span><span class="python_operator">, </span><span class="python_name">MyType</span><span class="python_enclosure">(</span><span class="python_number">16</span><span class="python_enclosure">))</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>




            <a href="#types" class="totoc">back to section top</a>
    </div>




    </div>



    
    
    <A name="pooling"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#types">The Types System</a>

               |   
            Next: <a href="#plugins">Plugins</a>
    </div>

        <h2>Connection Pooling</h2>
    </div>


        








    
    <A name="pooling"></a>
    
    <div class="sectionL1">

    
    

<p>This section describes the connection pool module of SQLAlchemy.  The <code>Pool</code> object it provides is normally embedded within an <code>Engine</code> instance.  For most cases, explicit access to the pool module is not required.  However, the <code>Pool</code> object can be used on its own, without the rest of SA, to manage DBAPI connections; this section describes that usage.  Also, this section will describe in more detail how to customize the pooling strategy used by an <code>Engine</code>.
</p>
<p>At the base of any database helper library is a system of efficiently acquiring connections to the database.  Since the establishment of a database connection is typically a somewhat expensive operation, an application needs a way to get at database connections repeatedly without incurring the full overhead each time.  Particularly for server-side web applications, a connection pool is the standard way to maintain a "pool" of database connections which are used over and over again among many requests.  Connection pools typically are configured to maintain a certain "size", which represents how many connections can be used simultaneously without resorting to creating more newly-established connections.
</p>


    
    <A name="pooling_establishing"></a>
    
    <div class="sectionL2">

    <h3>Establishing a Transparent Connection Pool</h3>
    
    

<p>Any DBAPI module can be "proxied" through the connection pool using the following technique (note that the usage of 'psycopg2' is <strong>just an example</strong>; substitute whatever DBAPI module you'd like):
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">pool </span><span class="python_keyword">as </span><span class="python_name">pool</span><span class="python_operator">
</span><span class="python_keyword">import </span><span class="python_name">psycopg2 </span><span class="python_keyword">as </span><span class="python_name">psycopg</span><span class="python_operator">
</span><span class="python_name">psycopg </span><span class="python_operator">= </span><span class="python_name">pool</span><span class="python_operator">.</span><span class="python_name">manage</span><span class="python_enclosure">(</span><span class="python_name">psycopg</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># then connect normally
</span><span class="python_name">connection </span><span class="python_operator">= </span><span class="python_name">psycopg</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">(</span><span class="python_name">database</span><span class="python_operator">=</span><span class="python_literal">'test'</span><span class="python_operator">, </span><span class="python_name">username</span><span class="python_operator">=</span><span class="python_literal">'scott'</span><span class="python_operator">, </span><span class="python_name">password</span><span class="python_operator">=</span><span class="python_literal">'tiger'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>This produces a <code>sqlalchemy.pool.DBProxy</code> object which supports the same <code>connect()</code> function as the original DBAPI module.  Upon connection, a connection proxy object is returned, which delegates its calls to a real DBAPI connection object.  This connection object is stored persistently within a connection pool (an instance of <code>sqlalchemy.pool.Pool</code>) that corresponds to the exact connection arguments sent to the <code>connect()</code> function.  <br></br>
</p>
<p>The connection proxy supports all of the methods on the original connection object, most of which are proxied via <code>__getattr__()</code>.  The <code>close()</code> method will return the connection to the pool, and the <code>cursor()</code> method will return a proxied cursor object.  Both the connection proxy and the cursor proxy will also return the underlying connection to the pool after they have both been garbage collected, which is detected via the <code>__del__()</code> method.
</p>
<p>Additionally, when connections are returned to the pool, a <code>rollback()</code> is issued on the connection unconditionally.  This is to release any locks still held by the connection that may have resulted from normal activity.
</p>
<p>By default, the <code>connect()</code> method will return the same connection that is already checked out in the current thread.  This allows a particular connection to be used in a given thread without needing to pass it around between functions.  To disable this behavior, specify <code>use_threadlocal=False</code> to the <code>manage()</code> function.
</p>



            <a href="#pooling" class="totoc">back to section top</a>
    </div>



    
    <A name="pooling_configuration"></a>
    
    <div class="sectionL2">

    <h3>Connection Pool Configuration</h3>
    
    

<p>For all types of Pool construction, which includes the "transparent proxy" described in the previous section, using an <code>Engine</code> via <code>create_engine()</code>, or constructing a pool through direct class instantiation, the options are generally the same.  Additional options may be available based on the specific subclass of <code>Pool</code> being used.
</p>
<p>For a description of all pool classes, see the <a href="sqlalchemy_pool.html#docstrings_sqlalchemy.pool">generated documentation</a>.
</p>
<p>Common options include:
</p>
<ul>
 <li>
     echo=False : if set to True, connections being pulled and retrieved from/to the pool will
        be logged to the standard output, as well as pool sizing information.  Echoing can also
        be achieved by enabling logging for the "sqlalchemy.pool" namespace.  When using create_engine(), 
        this option is specified as <code>echo_pool</code>.
 </li>

 <li>
     use_threadlocal=False : if set to True, repeated calls to connect() within the same
        application thread will be guaranteed to return the same connection object, if one has
        already been retrieved from the pool and has not been returned yet. This allows code to
        retrieve a connection from the pool, and then while still holding on to that connection,
        to call other functions which also ask the pool for a connection of the same arguments;
        those functions will act upon the same connection that the calling method is using.
        This option is overridden during <code>create_engine()</code>, corresponding to the "plain" or 
   "threadlocal" connection strategy.
 </li>

 <li>
     recycle=-1 : if set to non -1, a number of seconds between connection recycling, which
        means upon checkout, if this timeout is surpassed the connection will be closed and replaced
        with a newly opened connection.
 </li>
</ul>
<p>QueuePool options include:
</p>
<ul>
 <li>
     pool_size=5 : the size of the pool to be maintained. This is the
      largest number of connections that will be kept persistently in the pool. Note that the
      pool begins with no connections; once this number of connections is requested, that
      number of connections will remain.
 </li>

 <li>
     max_overflow=10 : the maximum overflow size of the pool. When the number of checked-out
      connections reaches the size set in pool_size, additional connections will be returned up
      to this limit. When those additional connections are returned to the pool, they are
      disconnected and discarded. It follows then that the total number of simultaneous
      connections the pool will allow is pool_size + max_overflow, and the total number of
      "sleeping" connections the pool will allow is pool_size. max_overflow can be set to -1 to
      indicate no overflow limit; no limit will be placed on the total number of concurrent
      connections.
 </li>

 <li>
     timeout=30 : the number of seconds to wait before giving up on returning a connection
 </li>
</ul>



            <a href="#pooling" class="totoc">back to section top</a>
    </div>



    
    <A name="pooling_custom"></a>
    
    <div class="sectionL2">

    <h3>Custom Pool Construction</h3>
    
    

<p>Besides using the transparent proxy, instances of <code>sqlalchemy.pool.Pool</code> can be created directly.  Constructing your own pool involves passing a callable used to create a connection.  Through this method, custom connection schemes can be made, such as a connection that automatically executes some initialization commands to start.  <br></br>
</p>

    

    <div class="sliding_code">
            <div class="codetitle">Constructing a QueuePool</div>
        <pre>
<span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">pool </span><span class="python_keyword">as </span><span class="python_name">pool</span><span class="python_operator">
</span><span class="python_keyword">import </span><span class="python_name">psycopg2</span><span class="python_operator">
</span>
<span class="python_keyword">def </span><span class="python_name">getconn</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_name">c </span><span class="python_operator">= </span><span class="python_name">psycopg2</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">(</span><span class="python_name">username</span><span class="python_operator">=</span><span class="python_literal">'ed'</span><span class="python_operator">, </span><span class="python_name">host</span><span class="python_operator">=</span><span class="python_literal">'127.0.0.1'</span><span class="python_operator">, </span><span class="python_name">dbname</span><span class="python_operator">=</span><span class="python_literal">'test'</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_comment"># execute an initialization function on the connection before returning
    </span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">cursor</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">(</span><span class="python_literal">"setup_encodings()"</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_keyword">return </span><span class="python_name">c</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">p </span><span class="python_operator">= </span><span class="python_name">pool</span><span class="python_operator">.</span><span class="python_name">QueuePool</span><span class="python_enclosure">(</span><span class="python_name">getconn</span><span class="python_operator">, </span><span class="python_name">max_overflow</span><span class="python_operator">=</span><span class="python_number">10</span><span class="python_operator">, </span><span class="python_name">pool_size</span><span class="python_operator">=</span><span class="python_number">5</span><span class="python_operator">, </span><span class="python_name">use_threadlocal</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Or with SingletonThreadPool:
</p>

    

    <div class="sliding_code">
            <div class="codetitle">Constructing a SingletonThreadPool</div>
        <pre>
<span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">pool </span><span class="python_keyword">as </span><span class="python_name">pool</span><span class="python_operator">
</span><span class="python_keyword">import </span><span class="python_name">sqlite</span><span class="python_operator">
</span>
<span class="python_keyword">def </span><span class="python_name">getconn</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_keyword">return </span><span class="python_name">sqlite</span><span class="python_operator">.</span><span class="python_name">connect</span><span class="python_enclosure">(</span><span class="python_name">filename</span><span class="python_operator">=</span><span class="python_literal">'myfile.db'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># SQLite connections require the SingletonThreadPool    
</span><span class="python_operator"></span><span class="python_name">p </span><span class="python_operator">= </span><span class="python_name">pool</span><span class="python_operator">.</span><span class="python_name">SingletonThreadPool</span><span class="python_enclosure">(</span><span class="python_name">getconn</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>




            <a href="#pooling" class="totoc">back to section top</a>
    </div>




    </div>



    
    
    <A name="plugins"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="#pooling">Connection Pooling</a>

               |   
            Next: <a href="docstrings.html#docstrings">API Documentation</a>
    </div>

        <h2>Plugins</h2>
    </div>


        








    
    <A name="plugins"></a>
    
    <div class="sectionL1">

    
    

<p>SQLAlchemy has a variety of extensions available which provide extra functionality to SA, either via explicit usage or by augmenting the core behavior.  Several of these extensions are designed to work together.
</p>


    
    <A name="plugins_declarative"></a>
    
    <div class="sectionL2">

    <h3>declarative</h3>
    
    

<p><strong>Author:</strong> Mike Bayer<br></br>
   <strong>Version:</strong> 0.4.4 or greater
</p>
<p><code>declarative</code> intends to be a fully featured replacement for the very old <code>activemapper</code> extension.  Its goal is to redefine the organization of class, <code>Table</code>, and <code>mapper()</code> constructs such that they can all be defined "at once" underneath a class declaration.   Unlike <code>activemapper</code>, it does not redefine normal SQLAlchemy configurational semantics - regular <code>Column</code>, <code>relation()</code> and other schema or ORM constructs are used in almost all cases.
</p>
<p><code>declarative</code> is a so-called "micro declarative layer"; it does not generate table or column names and requires almost as fully verbose a configuration as that of straight tables and mappers.  As an alternative, the <a href='http://elixir.ematia.de/'>Elixir</a> project is a full community-supported declarative layer for SQLAlchemy, and is recommended for its active-record-like semantics, its convention-based configuration, and plugin capabilities.
</p>
<p>SQLAlchemy object-relational configuration involves the usage of Table, mapper(), and class objects to define the three areas of configuration.
   declarative moves these three types of configuration underneath the individual mapped class. Regular SQLAlchemy schema and ORM constructs are used
   in most cases:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">declarative </span><span class="python_keyword">import </span><span class="python_name">declarative_base</span><span class="python_operator">
</span>
<span class="python_name">Base </span><span class="python_operator">= </span><span class="python_name">declarative_base</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">SomeClass</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'some_table'</span><span class="python_operator">
    </span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">name </span><span class="python_operator">=  </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, the <code>declarative_base</code> callable produces a new base class from which all mapped classes inherit from. When the class definition is
   completed, a new <code>Table</code> and <code>mapper()</code> have been generated, accessible via the <code>__table__</code> and <code>__mapper__</code> attributes on the
   <code>SomeClass</code> class.
</p>
<p>Attributes may be added to the class after its construction, and they will be added to the underlying <code>Table</code> and <code>mapper()</code> definitions as
   appropriate:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">SomeClass</span><span class="python_operator">.</span><span class="python_name">data </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'data'</span><span class="python_operator">, </span><span class="python_name">Unicode</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">SomeClass</span><span class="python_operator">.</span><span class="python_name">related </span><span class="python_operator">= </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">RelatedInfo</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Classes which are mapped explicitly using <code>mapper()</code> can interact freely with declarative classes. 
</p>
<p>The <code>declarative_base</code> base class contains a <code>MetaData</code> object where newly defined <code>Table</code> objects are collected.  This is accessed via the <code>metadata</code> class level accessor, so to create tables we can say:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite://'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">Base</span><span class="python_operator">.</span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">create_all</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>Engine</code> created above may also be directly associated with the declarative base class using the <code>engine</code> keyword argument, where it will be associated with the underlying <code>MetaData</code> object and allow SQL operations involving that metadata and its tables to make use of that engine automatically:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Base </span><span class="python_operator">= </span><span class="python_name">declarative_base</span><span class="python_enclosure">(</span><span class="python_name">engine</span><span class="python_operator">=</span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite://'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>Or, as <code>MetaData</code> allows, at any time using the <code>bind</code> attribute:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">Base</span><span class="python_operator">.</span><span class="python_name">metadata</span><span class="python_operator">.</span><span class="python_name">bind </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite://'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>declarative_base</code> can also receive a pre-created <code>MetaData</code> object, which allows a declarative setup to be associated with an already existing traditional collection of <code>Table</code> objects:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mymetadata </span><span class="python_operator">= </span><span class="python_name">MetaData</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">Base </span><span class="python_operator">= </span><span class="python_name">declarative_base</span><span class="python_enclosure">(</span><span class="python_name">metadata</span><span class="python_operator">=</span><span class="python_name">mymetadata</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Relations to other classes are done in the usual way, with the added feature that the class specified to <code>relation()</code> may be a string name. The
   "class registry" associated with <code>Base</code> is used at mapper compilation time to resolve the name into the actual class object, which is expected to
   have been defined once the mapper configuration is used:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'users'</span><span class="python_operator">
</span>
    <span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">
    </span><span class="python_name">addresses </span><span class="python_operator">= </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_literal">"Address"</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">"user"</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'addresses'</span><span class="python_operator">
</span>
    <span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">email </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">
    </span><span class="python_name">user_id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'users.id'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>Column constructs, since they are just that, are immediately usable, as below where we define a primary join condition on the <code>Address</code> class
   using them:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'addresses'</span><span class="python_operator">
</span>
    <span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">email </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'email'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">
    </span><span class="python_name">user_id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'users.id'</span><span class="python_enclosure">))</span><span class="python_operator">
    </span><span class="python_name">user </span><span class="python_operator">= </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">primaryjoin</span><span class="python_operator">=</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>When an explicit join condition or other configuration which depends 
   on multiple classes cannot be defined immediately due to some classes
   not yet being available, these can be defined after all classes have
   been created.  Attributes which are added to the class after
   its creation are associated with the Table/mapping in the same
   way as if they had been defined inline:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">addresses </span><span class="python_operator">= </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Address</span><span class="python_operator">, </span><span class="python_name">primaryjoin</span><span class="python_operator">=</span><span class="python_name">Address</span><span class="python_operator">.</span><span class="python_name">user_id</span><span class="python_operator">==</span><span class="python_name">User</span><span class="python_operator">.</span><span class="python_name">id</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Synonyms are one area where <code>declarative</code> needs to slightly change the usual SQLAlchemy configurational syntax. To define a
   getter/setter which proxies to an underlying attribute, use <code>synonym</code> with the <code>instruments</code> argument:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MyClass</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'sometable'</span><span class="python_operator">
</span>
    <span class="python_name">_attr </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'attr'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
    <span class="python_keyword">def </span><span class="python_name">_get_attr</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">_some_attr</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">_set_attr</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">attr</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">_some_attr </span><span class="python_operator">= </span><span class="python_name">attr</span><span class="python_operator">
    </span><span class="python_name">attr </span><span class="python_operator">= </span><span class="python_name">synonym</span><span class="python_enclosure">(</span><span class="python_literal">'_attr'</span><span class="python_operator">, </span><span class="python_name">instruments</span><span class="python_operator">=</span><span class="python_name">property</span><span class="python_enclosure">(</span><span class="python_name">_get_attr</span><span class="python_operator">, </span><span class="python_name">_set_attr</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>The above synonym is then usable as an instance attribute as well as a class-level expression construct:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">x </span><span class="python_operator">= </span><span class="python_name">MyClass</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">x</span><span class="python_operator">.</span><span class="python_name">attr </span><span class="python_operator">= </span><span class="python_literal">"some value"</span><span class="python_operator">
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_operator">.</span><span class="python_name">attr </span><span class="python_operator">== </span><span class="python_literal">'some other value'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">all</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>The <code>synonyn_for</code> decorator can accomplish the same task:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MyClass</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'sometable'</span><span class="python_operator">
</span>
    <span class="python_name">_attr </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'attr'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
    <span class="python_operator">@</span><span class="python_name">synonyn_for</span><span class="python_enclosure">(</span><span class="python_literal">'_attr'</span><span class="python_enclosure">)</span><span class="python_operator">
    @</span><span class="python_name">property</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">attr</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">_some_attr</span><span class="python_operator">
</span></pre>
    </div>
<p>Similarly, <code>comparable_using</code> is a front end for the <code>comparable_property</code> ORM function:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MyClass</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'sometable'</span><span class="python_operator">
</span>
    <span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
    <span class="python_operator">@</span><span class="python_name">comparable_using</span><span class="python_enclosure">(</span><span class="python_name">MyUpperCaseComparator</span><span class="python_enclosure">)</span><span class="python_operator">
    @</span><span class="python_name">property</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">uc_name</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_operator">.</span><span class="python_name">upper</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>As an alternative to <code>__tablename__</code>, a direct <code>Table</code> construct may be used.  The <code>Column</code> objects, which in this case require their names, will be added to the mapping just like a regular mapping to a table:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MyClass</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__table__ </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'my_table'</span><span class="python_operator">, </span><span class="python_name">Base</span><span class="python_operator">.</span><span class="python_name">metadata</span><span class="python_operator">,</span>
        <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
        <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span>
    <span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>This is the preferred approach when using reflected tables, as below:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">MyClass</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__table__ </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'my_table'</span><span class="python_operator">, </span><span class="python_name">Base</span><span class="python_operator">.</span><span class="python_name">metadata</span><span class="python_operator">, </span><span class="python_name">autoload</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Mapper arguments are specified using the <code>__mapper_args__</code> class variable. Note that the column objects declared on the class are immediately
   usable, as in this joined-table inheritance example:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">Person</span><span class="python_enclosure">(</span><span class="python_name">Base</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'people'</span><span class="python_operator">
    </span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">discriminator </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'type'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">
    </span><span class="python_name">__mapper_args__ </span><span class="python_operator">= </span><span class="python_enclosure">{</span><span class="python_literal">'polymorphic_on'</span><span class="python_operator">:</span><span class="python_name">discriminator</span><span class="python_enclosure">}</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Engineer</span><span class="python_enclosure">(</span><span class="python_name">Person</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_name">__tablename__ </span><span class="python_operator">= </span><span class="python_literal">'engineers'</span><span class="python_operator">
    </span><span class="python_name">__mapper_args__ </span><span class="python_operator">= </span><span class="python_enclosure">{</span><span class="python_literal">'polymorphic_identity'</span><span class="python_operator">:</span><span class="python_literal">'engineer'</span><span class="python_enclosure">}</span><span class="python_operator">
    </span><span class="python_name">id </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'people.id'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
    </span><span class="python_name">primary_language </span><span class="python_operator">= </span><span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'primary_language'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">50</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>For single-table inheritance, the <code>__tablename__</code> and <code>__table__</code> class variables are optional on a class when the class inherits from another
   mapped class.
</p>
<p>As a convenience feature, the <code>declarative_base()</code> sets a default constructor on classes which takes keyword arguments, and assigns them to the
   named attributes:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">e </span><span class="python_operator">= </span><span class="python_name">Engineer</span><span class="python_enclosure">(</span><span class="python_name">primary_language</span><span class="python_operator">=</span><span class="python_literal">'python'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Note that <code>declarative</code> has no integration built in with sessions, and is only intended as an optional syntax for the regular usage of mappers
   and Table objects. A typical application setup using <code>scoped_session</code> might look like:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">engine </span><span class="python_operator">= </span><span class="python_name">create_engine</span><span class="python_enclosure">(</span><span class="python_literal">'postgres://scott:tiger@localhost/test'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">Session </span><span class="python_operator">= </span><span class="python_name">scoped_session</span><span class="python_enclosure">(</span><span class="python_name">sessionmaker</span><span class="python_enclosure">(</span><span class="python_name">transactional</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_operator">, </span><span class="python_name">autoflush</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_operator">, </span><span class="python_name">bind</span><span class="python_operator">=</span><span class="python_name">engine</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_name">Base </span><span class="python_operator">= </span><span class="python_name">declarative_base</span><span class="python_enclosure">()</span><span class="python_operator">
</span></pre>
    </div>
<p>Mapped instances then make usage of <code>Session</code> in the usual way.
</p>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_associationproxy"></a>
    
    <div class="sectionL2">

    <h3>associationproxy</h3>
    
    

<p><strong>Author:</strong> Mike Bayer and Jason Kirtland<br></br>
   <strong>Version:</strong> 0.3.1 or greater
</p>
<p><code>associationproxy</code> is used to create a simplified, read/write view of a relationship.  It can be used to cherry-pick fields from a collection of related objects or to greatly simplify access to associated objects in an association relationship.
</p>


    
    <A name="plugins_associationproxy_simplifying"></a>
    
    <div class="sectionL3">

    <h3>Simplifying Association Object Relations</h3>
    
    

<p>Consider this "association object" mapping:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">users_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'users'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">64</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">keywords_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'keywords'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'keyword'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">64</span><span class="python_enclosure">))</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">userkeywords_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'userkeywords'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"users.id"</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
           <span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'keyword_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"keywords.id"</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
           <span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">keyword</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">keyword </span><span class="python_operator">= </span><span class="python_name">keyword</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'kw'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_operator">, </span><span class="python_name">secondary</span><span class="python_operator">=</span><span class="python_name">userkeywords_table</span><span class="python_enclosure">)</span>
    <span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_operator">, </span><span class="python_name">keywords_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Above are three simple tables, modeling users, keywords and a many-to-many relationship between the two.  These <code>Keyword</code> objects are little more than a container for a name, and accessing them via the relation is awkward:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">user </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'jek'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">kw</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_literal">'cheese inspector'</span><span class="python_enclosure">))</span><span class="python_operator">
</span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">kw</span><span class="python_operator">
</span><span class="python_comment"># [&lt;__main__.Keyword object at 0xb791ea0c&gt;]
</span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">kw</span><span class="python_enclosure">[</span><span class="python_number">0</span><span class="python_enclosure">]</span><span class="python_operator">.</span><span class="python_name">keyword</span><span class="python_operator">
</span><span class="python_comment"># 'cheese inspector'
</span><span class="python_keyword">print </span><span class="python_enclosure">[</span><span class="python_name">keyword</span><span class="python_operator">.</span><span class="python_name">keyword </span><span class="python_keyword">for </span><span class="python_name">keyword </span><span class="python_keyword">in </span><span class="python_name">u</span><span class="python_operator">.</span><span class="python_name">_keywords</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_comment"># ['cheese inspector']
</span><span class="python_operator"></span></pre>
    </div>
<p>With <code>association_proxy</code> you have a "view" of the relation that contains just the <code>.keyword</code> of the related objects.  The proxy is a Python property, and unlike the mapper relation, is defined in your class:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">associationproxy </span><span class="python_keyword">import </span><span class="python_name">association_proxy</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
</span>
    <span class="python_comment"># proxy the 'keyword' attribute from the 'kw' relation
    </span><span class="python_operator"></span><span class="python_name">keywords </span><span class="python_operator">= </span><span class="python_name">association_proxy</span><span class="python_enclosure">(</span><span class="python_literal">'kw'</span><span class="python_operator">, </span><span class="python_literal">'keyword'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># ...
</span><span class="python_operator"></span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">kw</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">__main__</span><span class="python_operator">.</span><span class="python_name">Keyword object at </span><span class="python_number">0xb791ea0c</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_literal">'cheese inspector'</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_literal">'snack ninja'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_literal">'cheese inspector'</span><span class="python_operator">, </span><span class="python_literal">'snack ninja'</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">kw</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_operator">&lt;</span><span class="python_name">__main__</span><span class="python_operator">.</span><span class="python_name">Keyword object at </span><span class="python_number">0x9272a4c</span><span class="python_operator">&gt;, &lt;</span><span class="python_name">__main__</span><span class="python_operator">.</span><span class="python_name">Keyword object at </span><span class="python_number">0xb7b396ec</span><span class="python_operator">&gt;</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>The proxy is read/write.  New associated objects are created on demand when values are added to the proxy, and modifying or removing an entry through the proxy also affects the underlying collection.
</p>
<ul>
 <li>
     The association proxy property is backed by a mapper-defined relation, either a collection or scalar.
 </li>

 <li>
     You can access and modify both the proxy and the backing relation. Changes in one are immediate in the other.
 </li>

 <li>
     The proxy acts like the type of the underlying collection.  A list gets a list-like proxy, a dict a dict-like proxy, and so on.
 </li>

 <li>
     Multiple proxies for the same relation are fine.
 </li>

 <li>
     Proxies are lazy, and won't triger a load of the backing relation until they are accessed.
 </li>

 <li>
     The relation is inspected to determine the type of the related objects.
 </li>

 <li>
     To construct new instances, the type is called with the value being assigned, or key and value for dicts.
 </li>

 <li>
     A <code>creator</code> function can be used to create instances instead.
 </li>
</ul>
<p>Above, the <code>Keyword.__init__</code> takes a single argument <code>keyword</code>, which maps conveniently to the value being set through the proxy.  A <code>creator</code> function could have been used instead if more flexiblity was required.
</p>
<p>Because the proxies are backed a regular relation collection, all of the usual hooks and patterns for using collections are still in effect.  The most convenient behavior is the automatic setting of "parent"-type relationships on assignment.  In the example above, nothing special had to be done to associate the Keyword to the User.  Simply adding it to the collection is sufficient.
</p>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_associationproxy_simplifying"></a>
    
    <div class="sectionL3">

    <h3>Simplifying Association Object Relations</h3>
    
    

<p>Association proxies are also useful for keeping <b>association objects</b> out the way during regular use.  For example, the  <code>userkeywords</code> table might have a bunch of auditing columns that need to get updated when changes are made- columns that are updated but seldom, if ever, accessed in your application.  A proxy can provide a very natural access pattern for the relation.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">associationproxy </span><span class="python_keyword">import </span><span class="python_name">association_proxy</span><span class="python_operator">
</span>
<span class="python_comment"># users_table and keywords_table tables as above, then:
</span>
<span class="python_name">userkeywords_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'userkeywords'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'user_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"users.id"</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'keyword_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">"keywords.id"</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_comment"># add some auditing columns</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'updated_at'</span><span class="python_operator">, </span><span class="python_name">DateTime</span><span class="python_operator">, </span><span class="python_name">default</span><span class="python_operator">=</span><span class="python_name">datetime</span><span class="python_operator">.</span><span class="python_name">now</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'updated_by'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">default</span><span class="python_operator">=</span><span class="python_name">get_current_uid</span><span class="python_operator">, </span><span class="python_name">onupdate</span><span class="python_operator">=</span><span class="python_name">get_current_uid</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_keyword">def </span><span class="python_name">_create_uk_by_keyword</span><span class="python_enclosure">(</span><span class="python_name">keyword</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_literal">"""A creator function."""</span><span class="python_operator">
    </span><span class="python_keyword">return </span><span class="python_name">UserKeyword</span><span class="python_enclosure">(</span><span class="python_name">keyword</span><span class="python_operator">=</span><span class="python_name">keyword</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
    </span><span class="python_name">keywords </span><span class="python_operator">= </span><span class="python_name">association_proxy</span><span class="python_enclosure">(</span><span class="python_literal">'user_keywords'</span><span class="python_operator">, </span><span class="python_literal">'keyword'</span><span class="python_operator">, </span><span class="python_name">creator</span><span class="python_operator">=</span><span class="python_name">_create_uk_by_keyword</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">keyword</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">keyword </span><span class="python_operator">= </span><span class="python_name">keyword</span><span class="python_operator">
    </span><span class="python_keyword">def </span><span class="python_name">__repr__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_keyword">return </span><span class="python_literal">'Keyword(%s)' </span><span class="python_operator">% </span><span class="python_name">repr</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">keyword</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">UserKeyword</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">user</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_operator">, </span><span class="python_name">keyword</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">user </span><span class="python_operator">= </span><span class="python_name">user</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">keyword </span><span class="python_operator">= </span><span class="python_name">keyword</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'user_keywords'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">UserKeyword</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_operator">, </span><span class="python_name">keywords_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">UserKeyword</span><span class="python_operator">, </span><span class="python_name">userkeywords_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'user'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_literal">'keyword'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span>
<span class="python_name">user </span><span class="python_operator">= </span><span class="python_name">User</span><span class="python_enclosure">(</span><span class="python_literal">'log'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">kw1  </span><span class="python_operator">= </span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_literal">'new_from_blammo'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># Adding a Keyword requires creating a UserKeyword association object
</span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">user_keywords</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">UserKeyword</span><span class="python_enclosure">(</span><span class="python_name">user</span><span class="python_operator">, </span><span class="python_name">kw1</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_comment"># And accessing Keywords requires traversing UserKeywords
</span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">user_keywords</span><span class="python_enclosure">[</span><span class="python_number">0</span><span class="python_enclosure">]</span><span class="python_operator">
</span><span class="python_comment"># &lt;__main__.UserKeyword object at 0xb79bbbec&gt;
</span>
<span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">user_keywords</span><span class="python_enclosure">[</span><span class="python_number">0</span><span class="python_enclosure">]</span><span class="python_operator">.</span><span class="python_name">keyword</span><span class="python_operator">
</span><span class="python_comment"># Keyword('new_from_blammo')
</span>
<span class="python_comment"># Lots of work.
</span>
<span class="python_comment"># It's much easier to go through the association proxy!
</span><span class="python_keyword">for </span><span class="python_name">kw </span><span class="python_keyword">in </span><span class="python_enclosure">(</span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_literal">'its_big'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_literal">'its_heavy'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">Keyword</span><span class="python_enclosure">(</span><span class="python_literal">'its_wood'</span><span class="python_enclosure">))</span><span class="python_operator">:
    </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">kw</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">print </span><span class="python_name">user</span><span class="python_operator">.</span><span class="python_name">keywords</span><span class="python_operator">
</span><span class="python_comment"># [Keyword('new_from_blammo'), Keyword('its_big'), Keyword('its_heavy'), Keyword('its_wood')]
</span><span class="python_operator"></span></pre>
    </div>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_associationproxy_building"></a>
    
    <div class="sectionL3">

    <h3>Building Complex Views</h3>
    
    


    

    <div class="sliding_code">
        <pre>
<span class="python_name">stocks </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">"stocks"</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'symbol'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">10</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'description'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'last_price'</span><span class="python_operator">, </span><span class="python_name">Numeric</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">brokers </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">"brokers"</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">,</span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
   <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">100</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">nullable</span><span class="python_operator">=</span><span class="python_name">False</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">holdings </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">"holdings"</span><span class="python_operator">, </span><span class="python_name">meta</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'broker_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'brokers.id'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'symbol'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">(</span><span class="python_number">10</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'stocks.symbol'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
  <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'shares'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span>
<span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>Above are three tables, modeling stocks, their brokers and the number of shares of a stock held by each broker.  This situation is quite different from the association example above.  <code>shares</code> is a <em>property of the relation</em>, an important one that we need to use all the time.
</p>
<p>For this example, it would be very convenient if <code>Broker</code> objects had a dictionary collection that mapped <code>Stock</code> instances to the shares held for each.  That's easy.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">associationproxy </span><span class="python_keyword">import </span><span class="python_name">association_proxy</span><span class="python_operator">
</span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">orm</span><span class="python_operator">.</span><span class="python_name">collections </span><span class="python_keyword">import </span><span class="python_name">attribute_mapped_collection</span><span class="python_operator">
</span>
<span class="python_keyword">def </span><span class="python_name">_create_holding</span><span class="python_enclosure">(</span><span class="python_name">stock</span><span class="python_operator">, </span><span class="python_name">shares</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_literal">"""A creator function, constructs Holdings from Stock and share quantity."""</span><span class="python_operator">
    </span><span class="python_keyword">return </span><span class="python_name">Holding</span><span class="python_enclosure">(</span><span class="python_name">stock</span><span class="python_operator">=</span><span class="python_name">stock</span><span class="python_operator">, </span><span class="python_name">shares</span><span class="python_operator">=</span><span class="python_name">shares</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Broker</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">name</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">name </span><span class="python_operator">= </span><span class="python_name">name</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_name">holdings </span><span class="python_operator">= </span><span class="python_name">association_proxy</span><span class="python_enclosure">(</span><span class="python_literal">'by_stock'</span><span class="python_operator">, </span><span class="python_literal">'shares'</span><span class="python_operator">, </span><span class="python_name">creator</span><span class="python_operator">=</span><span class="python_name">_create_holding</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Stock</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">symbol</span><span class="python_operator">, </span><span class="python_name">description</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">symbol </span><span class="python_operator">= </span><span class="python_name">symbol</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">description </span><span class="python_operator">= </span><span class="python_name">description</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">last_price </span><span class="python_operator">= </span><span class="python_number">0</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Holding</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">def </span><span class="python_name">__init__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">, </span><span class="python_name">broker</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_operator">, </span><span class="python_name">stock</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_operator">, </span><span class="python_name">shares</span><span class="python_operator">=</span><span class="python_number">0</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">broker </span><span class="python_operator">= </span><span class="python_name">broker</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">stock </span><span class="python_operator">= </span><span class="python_name">stock</span><span class="python_operator">
        </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">shares </span><span class="python_operator">= </span><span class="python_name">shares</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Stock</span><span class="python_operator">, </span><span class="python_name">stocks_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Broker</span><span class="python_operator">, </span><span class="python_name">brokers_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'by_stock'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Holding</span><span class="python_operator">,</span>
        <span class="python_name">collection_class</span><span class="python_operator">=</span><span class="python_name">attribute_mapped_collection</span><span class="python_enclosure">(</span><span class="python_literal">'stock'</span><span class="python_enclosure">))</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Holding</span><span class="python_operator">, </span><span class="python_name">holdings_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'stock'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Stock</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
    <span class="python_literal">'broker'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Broker</span><span class="python_enclosure">)</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span></pre>
    </div>
<p>Above, we've set up the 'by_stock' relation collection to act as a dictionary, using the <code>.stock</code> property of each Holding as a key.
</p>
<p>Populating and accessing that dictionary manually is slightly inconvenient because of the complexity of the Holdings association object:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">stock </span><span class="python_operator">= </span><span class="python_name">Stock</span><span class="python_enclosure">(</span><span class="python_literal">'ZZK'</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">broker </span><span class="python_operator">= </span><span class="python_name">Broker</span><span class="python_enclosure">(</span><span class="python_literal">'paj'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">broker</span><span class="python_operator">.</span><span class="python_name">holdings</span><span class="python_enclosure">[</span><span class="python_name">stock</span><span class="python_enclosure">] </span><span class="python_operator">= </span><span class="python_name">Holding</span><span class="python_enclosure">(</span><span class="python_name">broker</span><span class="python_operator">, </span><span class="python_name">stock</span><span class="python_operator">, </span><span class="python_number">10</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_keyword">print </span><span class="python_name">broker</span><span class="python_operator">.</span><span class="python_name">holdings</span><span class="python_enclosure">[</span><span class="python_name">stock</span><span class="python_enclosure">]</span><span class="python_operator">.</span><span class="python_name">shares</span><span class="python_operator">
</span><span class="python_comment"># 10
</span><span class="python_operator"></span></pre>
    </div>
<p>The <code>by_stock</code> proxy we've added to the <code>Broker</code> class hides the details of the <code>Holding</code> while also giving access to <code>.shares</code>:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">for </span><span class="python_name">stock </span><span class="python_keyword">in </span><span class="python_enclosure">(</span><span class="python_name">Stock</span><span class="python_enclosure">(</span><span class="python_literal">'JEK'</span><span class="python_enclosure">)</span><span class="python_operator">, </span><span class="python_name">Stock</span><span class="python_enclosure">(</span><span class="python_literal">'STPZ'</span><span class="python_enclosure">))</span><span class="python_operator">:
    </span><span class="python_name">broker</span><span class="python_operator">.</span><span class="python_name">holdings</span><span class="python_enclosure">[</span><span class="python_name">stock</span><span class="python_enclosure">] </span><span class="python_operator">= </span><span class="python_number">123</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">for </span><span class="python_name">stock</span><span class="python_operator">, </span><span class="python_name">shares </span><span class="python_keyword">in </span><span class="python_name">broker</span><span class="python_operator">.</span><span class="python_name">holdings</span><span class="python_operator">.</span><span class="python_name">items</span><span class="python_enclosure">()</span><span class="python_operator">:
    </span><span class="python_keyword">print </span><span class="python_name">stock</span><span class="python_operator">, </span><span class="python_name">shares</span><span class="python_operator">
</span>
<span class="python_comment"># lets take a peek at that holdings_table after committing changes to the db
</span><span class="python_operator"></span><span class="python_keyword">print </span><span class="python_name">list</span><span class="python_enclosure">(</span><span class="python_name">holdings_table</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">()</span><span class="python_operator">.</span><span class="python_name">execute</span><span class="python_enclosure">())</span><span class="python_operator">
</span><span class="python_comment"># [(1, 'ZZK', 10), (1, 'JEK', 123), (1, 'STEPZ', 123)]
</span><span class="python_operator"></span></pre>
    </div>
<p>Further examples can be found in the <code>examples/</code> directory in the SQLAlchemy distribution.
</p>
<p>The <code>association_proxy</code> convenience function is not present in SQLAlchemy versions 0.3.1 through 0.3.7, instead instantiate the class directly:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">associationproxy </span><span class="python_keyword">import </span><span class="python_name">AssociationProxy</span><span class="python_operator">
</span>
<span class="python_keyword">class </span><span class="python_name">Article</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
   </span><span class="python_name">keywords </span><span class="python_operator">= </span><span class="python_name">AssociationProxy</span><span class="python_enclosure">(</span><span class="python_literal">'keyword_associations'</span><span class="python_operator">, </span><span class="python_literal">'keyword'</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>




    </div>



    
    <A name="plugins_orderinglist"></a>
    
    <div class="sectionL2">

    <h3>orderinglist</h3>
    
    

<p><strong>Author:</strong> Jason Kirtland
</p>
<p><code>orderinglist</code> is a helper for mutable ordered relations.  It will intercept
   list operations performed on a relation collection and automatically
   synchronize changes in list position with an attribute on the related objects.
   (See <b>advdatamapping_properties_entitycollections</b> for more information on the general pattern.)
</p>
<p>Example: Two tables that store slides in a presentation.  Each slide
   has a number of bullet points, displayed in order by the 'position'
   column on the bullets table.  These bullets can be inserted and re-ordered
   by your end users, and you need to update the 'position' column of all
   affected rows when changes are made.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">slides_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'Slides'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
                     <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
                     <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'name'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">bullets_table </span><span class="python_operator">= </span><span class="python_name">Table</span><span class="python_enclosure">(</span><span class="python_literal">'Bullets'</span><span class="python_operator">, </span><span class="python_name">metadata</span><span class="python_operator">,</span>
                      <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
                      <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'slide_id'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'Slides.id'</span><span class="python_enclosure">))</span><span class="python_operator">,</span>
                      <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'position'</span><span class="python_operator">, </span><span class="python_name">Integer</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
                      <span class="python_name">Column</span><span class="python_enclosure">(</span><span class="python_literal">'text'</span><span class="python_operator">, </span><span class="python_name">String</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_operator"> </span><span class="python_keyword">class </span><span class="python_name">Slide</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
     </span><span class="python_keyword">pass</span><span class="python_operator">
 </span><span class="python_keyword">class </span><span class="python_name">Bullet</span><span class="python_enclosure">(</span><span class="python_name">object</span><span class="python_enclosure">)</span><span class="python_operator">:
     </span><span class="python_keyword">pass</span><span class="python_operator">
</span>
 <span class="python_operator"></span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Slide</span><span class="python_operator">, </span><span class="python_name">slides_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
       <span class="python_literal">'bullets'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Bullet</span><span class="python_operator">, </span><span class="python_name">order_by</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">bullets_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">position</span><span class="python_enclosure">])</span>
 <span class="python_enclosure">})</span><span class="python_operator">
 </span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Bullet</span><span class="python_operator">, </span><span class="python_name">bullets_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span></pre>
    </div>
<p>The standard relation mapping will produce a list-like attribute on each Slide
   containing all related Bullets, but coping with changes in ordering is totally
   your responsibility.  If you insert a Bullet into that list, there is no
   magic- it won't have a position attribute unless you assign it it one, and
   you'll need to manually renumber all the subsequent Bullets in the list to
   accommodate the insert.
</p>
<p>An <code>orderinglist</code> can automate this and manage the 'position' attribute on all
   related bullets for you.
</p>

    

    <div class="sliding_code">
        <pre> 
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Slide</span><span class="python_operator">, </span><span class="python_name">slides_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
<span class="python_literal">'bullets'</span><span class="python_operator">: </span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">Bullet</span><span class="python_operator">,</span>
                    <span class="python_name">collection_class</span><span class="python_operator">=</span><span class="python_name">ordering_list</span><span class="python_enclosure">(</span><span class="python_literal">'position'</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
                    <span class="python_name">order_by</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">bullets_table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">position</span><span class="python_enclosure">])</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Bullet</span><span class="python_operator">, </span><span class="python_name">bullets_table</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">s </span><span class="python_operator">= </span><span class="python_name">Slide</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">bullets</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Bullet</span><span class="python_enclosure">())</span><span class="python_operator">
</span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">bullets</span><span class="python_operator">.</span><span class="python_name">append</span><span class="python_enclosure">(</span><span class="python_name">Bullet</span><span class="python_enclosure">())</span><span class="python_operator">
</span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">bullets</span><span class="python_enclosure">[</span><span class="python_number">1</span><span class="python_enclosure">]</span><span class="python_operator">.</span><span class="python_name">position</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_number">1</span><span class="python_operator">
</span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">bullets</span><span class="python_operator">.</span><span class="python_name">insert</span><span class="python_enclosure">(</span><span class="python_number">1</span><span class="python_operator">, </span><span class="python_name">Bullet</span><span class="python_enclosure">())</span><span class="python_operator">
</span><span class="python_name">s</span><span class="python_operator">.</span><span class="python_name">bullets</span><span class="python_enclosure">[</span><span class="python_number">2</span><span class="python_enclosure">]</span><span class="python_operator">.</span><span class="python_name">position</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_number">2</span><span class="python_operator">
</span></pre>
    </div>
<p>Use the <code>ordering_list</code> function to set up the <code>collection_class</code> on relations
   (as in the mapper example above).  This implementation depends on the list
   starting in the proper order, so be SURE to put an order_by on your relation.
</p>
<p><code>ordering_list</code> takes the name of the related object's ordering attribute as
   an argument.  By default, the zero-based integer index of the object's
   position in the <code>ordering_list</code> is synchronized with the ordering attribute:
   index 0 will get position 0, index 1 position 1, etc.  To start numbering at 1
   or some other integer, provide <code>count_from=1</code>.
</p>
<p>Ordering values are not limited to incrementing integers.  Almost any scheme
   can implemented by supplying a custom <code>ordering_func</code> that maps a Python list
   index to any value you require.  See the <a href="sqlalchemy_ext_orderinglist.html#docstrings_sqlalchemy.ext.orderinglist">module
documentation</a> for more
   information, and also check out the unit tests for examples of stepped
   numbering, alphabetical and Fibonacci numbering.
</p>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_sqlsoup"></a>
    
    <div class="sectionL2">

    <h3>SqlSoup</h3>
    
    

<p><strong>Author:</strong> Jonathan Ellis
</p>
<p>SqlSoup creates mapped classes on the fly from tables, which are automatically reflected from the database based on name.  It is essentially a nicer version of the "row data gateway" pattern.
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">sqlsoup </span><span class="python_keyword">import </span><span class="python_name">SqlSoup</span><span class="python_operator">
</span><span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">soup </span><span class="python_operator">= </span><span class="python_name">SqlSoup</span><span class="python_enclosure">(</span><span class="python_literal">'sqlite:///'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_literal">&gt;&gt;&gt; </span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">order_by</span><span class="python_operator">=</span><span class="python_enclosure">[</span><span class="python_name">db</span><span class="python_operator">.</span><span class="python_name">users</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">name</span><span class="python_enclosure">])</span><span class="python_operator">
</span><span class="python_enclosure">[</span><span class="python_name">MappedUsers</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'Bhargan Basepair'</span><span class="python_operator">,</span><span class="python_name">email</span><span class="python_operator">=</span><span class="python_literal">'basepair@example.edu'</span><span class="python_operator">,</span><span class="python_name">password</span><span class="python_operator">=</span><span class="python_literal">'basepair'</span><span class="python_operator">,</span><span class="python_name">classname</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_operator">,</span><span class="python_name">admin</span><span class="python_operator">=</span><span class="python_number">1</span><span class="python_enclosure">)</span><span class="python_operator">,</span>
 <span class="python_name">MappedUsers</span><span class="python_enclosure">(</span><span class="python_name">name</span><span class="python_operator">=</span><span class="python_literal">'Joe Student'</span><span class="python_operator">,</span><span class="python_name">email</span><span class="python_operator">=</span><span class="python_literal">'student@example.edu'</span><span class="python_operator">,</span><span class="python_name">password</span><span class="python_operator">=</span><span class="python_literal">'student'</span><span class="python_operator">,</span><span class="python_name">classname</span><span class="python_operator">=</span><span class="python_name">None</span><span class="python_operator">,</span><span class="python_name">admin</span><span class="python_operator">=</span><span class="python_number">0</span><span class="python_enclosure">)]</span><span class="python_operator">
</span></pre>
    </div>
<p>Full SqlSoup documentation is on the <a href='http://www.sqlalchemy.org/trac/wiki/SqlSoup'>SQLAlchemy Wiki</a>.
</p>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_deprecated"></a>
    
    <div class="sectionL2">

    <h3>Deprecated Extensions</h3>
    
    

<p>A lot of our extensions are deprecated.  But this is a good thing.  Why ?  Because all of them have been refined and focused, and rolled into the core of SQLAlchemy.  So they aren't removed, they've just graduated into fully integrated features.  Below we describe a set of extensions which are present in 0.4 but are deprecated.
</p>


    
    <A name="plugins_deprecated_selectresults"></a>
    
    <div class="sectionL3">

    <h3>SelectResults</h3>
    
    

<p><strong>Author:</strong> Jonas Borgström
</p>
<p><em>NOTE:</em> As of version 0.3.6 of SQLAlchemy, most behavior of <code>SelectResults</code> has been rolled into the base <code>Query</code> object.  Explicit usage of <code>SelectResults</code> is therefore no longer needed.
</p>
<p><code>SelectResults</code> gives transformative behavior to the results returned from the <code>select</code> and <code>select_by</code> methods of <code>Query</code>. 
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">selectresults </span><span class="python_keyword">import </span><span class="python_name">SelectResults</span><span class="python_operator">
</span>
<span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_enclosure">)</span><span class="python_operator">
</span><span class="python_name">res </span><span class="python_operator">= </span><span class="python_name">SelectResults</span><span class="python_enclosure">(</span><span class="python_name">query</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_name">res </span><span class="python_operator">= </span><span class="python_name">res</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">column </span><span class="python_operator">== </span><span class="python_literal">"something"</span><span class="python_enclosure">) </span><span class="python_comment"># adds a WHERE clause (or appends to the existing via "and")</span><span class="python_operator">
</span><span class="python_name">res </span><span class="python_operator">= </span><span class="python_name">res</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">([</span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">column</span><span class="python_enclosure">]) </span><span class="python_comment"># adds an ORDER BY clause</span><span class="python_operator">
</span>
<span class="python_keyword">for </span><span class="python_name">x </span><span class="python_keyword">in </span><span class="python_name">res</span><span class="python_enclosure">[</span><span class="python_operator">:</span><span class="python_number">10</span><span class="python_enclosure">]</span><span class="python_operator">:  </span><span class="python_comment"># Fetch and print the top ten instances - adds OFFSET 0 LIMIT 10 or equivalent</span><span class="python_operator">
  </span><span class="python_keyword">print </span><span class="python_name">x</span><span class="python_operator">.</span><span class="python_name">column2</span><span class="python_operator">
</span>
<span class="python_comment"># evaluate as a list, which executes the query
</span><span class="python_operator"></span><span class="python_name">x </span><span class="python_operator">= </span><span class="python_name">list</span><span class="python_enclosure">(</span><span class="python_name">res</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_comment"># Count how many instances that have column2 &gt; 42
# and column == "something"
</span><span class="python_keyword">print </span><span class="python_name">res</span><span class="python_operator">.</span><span class="python_name">filter</span><span class="python_enclosure">(</span><span class="python_name">table</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">column2 </span><span class="python_operator">&gt; </span><span class="python_number">42</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">count</span><span class="python_enclosure">()</span><span class="python_operator">
</span>
<span class="python_comment"># select() is a synonym for filter()
</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">column</span><span class="python_operator">==</span><span class="python_literal">"something"</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">order_by</span><span class="python_enclosure">([</span><span class="python_name">mytable</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">column</span><span class="python_enclosure">])[</span><span class="python_number">2</span><span class="python_operator">:</span><span class="python_number">7</span><span class="python_enclosure">]</span><span class="python_operator">
</span></pre>
    </div>
<p>An important facet of SelectResults is that the actual SQL execution does not occur until the object is used in a list or iterator context.  This means you can call any number of transformative methods (including <code>filter</code>, <code>order_by</code>, list range expressions, etc) before any SQL is actually issued.
</p>
<p>Configuration of SelectResults may be per-Query, per Mapper, or per application:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">from </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">ext</span><span class="python_operator">.</span><span class="python_name">selectresults </span><span class="python_keyword">import </span><span class="python_name">SelectResults</span><span class="python_operator">, </span><span class="python_name">SelectResultsExt</span><span class="python_operator">
</span>
<span class="python_comment"># construct a SelectResults for an individual Query
</span><span class="python_name">sel </span><span class="python_operator">= </span><span class="python_name">SelectResults</span><span class="python_enclosure">(</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_comment"># construct a Mapper where the Query.select()/select_by() methods will return a SelectResults:
</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">MyClass</span><span class="python_operator">, </span><span class="python_name">mytable</span><span class="python_operator">, </span><span class="python_name">extension</span><span class="python_operator">=</span><span class="python_name">SelectResultsExt</span><span class="python_enclosure">())</span><span class="python_operator">
</span>
<span class="python_comment"># globally configure all Mappers to return SelectResults, using the "selectresults" mod
</span><span class="python_keyword">import </span><span class="python_name">sqlalchemy</span><span class="python_operator">.</span><span class="python_name">mods</span><span class="python_operator">.</span><span class="python_name">selectresults</span><span class="python_operator">
</span></pre>
    </div>
<p>SelectResults greatly enhances querying and is highly recommended.  For example, heres an example of constructing a query using a combination of joins and outerjoins:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_operator">, </span><span class="python_name">users_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
    <span class="python_literal">'orders'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Order</span><span class="python_operator">, </span><span class="python_name">orders_table</span><span class="python_operator">, </span><span class="python_name">properties</span><span class="python_operator">=</span><span class="python_enclosure">{</span>
        <span class="python_literal">'items'</span><span class="python_operator">:</span><span class="python_name">relation</span><span class="python_enclosure">(</span><span class="python_name">mapper</span><span class="python_enclosure">(</span><span class="python_name">Item</span><span class="python_operator">, </span><span class="python_name">items_table</span><span class="python_enclosure">))</span>
    <span class="python_enclosure">}))</span>
<span class="python_enclosure">})</span><span class="python_operator">
</span><span class="python_name">session </span><span class="python_operator">= </span><span class="python_name">create_session</span><span class="python_enclosure">()</span><span class="python_operator">
</span><span class="python_name">query </span><span class="python_operator">= </span><span class="python_name">SelectResults</span><span class="python_enclosure">(</span><span class="python_name">session</span><span class="python_operator">.</span><span class="python_name">query</span><span class="python_enclosure">(</span><span class="python_name">User</span><span class="python_enclosure">))</span><span class="python_operator">
</span>
<span class="python_name">result </span><span class="python_operator">= </span><span class="python_name">query</span><span class="python_operator">.</span><span class="python_name">outerjoin_to</span><span class="python_enclosure">(</span><span class="python_literal">'orders'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">outerjoin_to</span><span class="python_enclosure">(</span><span class="python_literal">'items'</span><span class="python_enclosure">)</span><span class="python_operator">.</span><span class="python_name">select</span><span class="python_enclosure">(</span><span class="python_name">or_</span><span class="python_enclosure">(</span><span class="python_name">Order</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">order_id</span><span class="python_operator">==</span><span class="python_name">None</span><span class="python_operator">,</span><span class="python_name">Item</span><span class="python_operator">.</span><span class="python_name">c</span><span class="python_operator">.</span><span class="python_name">item_id</span><span class="python_operator">==</span><span class="python_number">2</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>For a full listing of methods, see the <b>generated documentation</b>.
</p>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_deprecated_sessioncontext"></a>
    
    <div class="sectionL3">

    <h3>SessionContext</h3>
    
    

<p><strong>Author:</strong>  Daniel Miller
</p>
<p>The <code>SessionContext</code> extension is still available in the 0.4 release of SQLAlchemy, but has been deprecated in favor of the <a href="#unitofwork_contextual">scoped_session()</a> function, which provides a class-like object that constructs a <code>Session</code> on demand which references a thread-local scope.  <br></br>
</p>
<p>For docs on <code>SessionContext</code>, see the SQLAlchemy 0.3 documentation.
</p>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_deprecated_assignmapper"></a>
    
    <div class="sectionL3">

    <h3>assignmapper</h3>
    
    

<p><strong>Author:</strong> Mike Bayer
</p>
<p>The <code>assignmapper</code> extension is still available in the 0.4 release of SQLAlchemy, but has been deprecated in favor of the <a href="#unitofwork_contextual">scoped_session()</a> function, which provides a <code>mapper</code> callable that works similarly to <code>assignmapper</code>.
</p>
<p>For docs on <code>assignmapper</code>, see the SQLAlchemy 0.3 documentation.
</p>



            <a href="#plugins" class="totoc">back to section top</a>
    </div>



    
    <A name="plugins_deprecated_activemapper"></a>
    
    <div class="sectionL3">

    <h3>ActiveMapper</h3>
    
    

<p><strong>Author:</strong> Jonathan LaCour
</p>
<p>Please note that ActiveMapper has been deprecated in favor of either <a href='http://elixir.ematia.de/'>Elixir</a>, a comprehensive solution to declarative mapping, or <a href="#plugins_declarative">declarative</a>, a built in convenience tool which reorganizes <code>Table</code> and <code>mapper()</code> configuration.
</p>
<p>ActiveMapper is a so-called "declarative layer" which allows the construction of a class, a <code>Table</code>, and a <code>Mapper</code> all in one step:
</p>

    

    <div class="sliding_code">
        <pre>
<span class="python_keyword">class </span><span class="python_name">Person</span><span class="python_enclosure">(</span><span class="python_name">ActiveMapper</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">class </span><span class="python_name">mapping</span><span class="python_operator">:
        </span><span class="python_name">id          </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">full_name   </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">first_name  </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">middle_name </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">last_name   </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">birth_date  </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">DateTime</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">ssn         </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">gender      </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">home_phone  </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">cell_phone  </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">work_phone  </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">prefs_id    </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">foreign_key</span><span class="python_operator">=</span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'preferences.id'</span><span class="python_enclosure">))</span><span class="python_operator">
        </span><span class="python_name">addresses   </span><span class="python_operator">= </span><span class="python_name">one_to_many</span><span class="python_enclosure">(</span><span class="python_literal">'Address'</span><span class="python_operator">, </span><span class="python_name">colname</span><span class="python_operator">=</span><span class="python_literal">'person_id'</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'person'</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">preferences </span><span class="python_operator">= </span><span class="python_name">one_to_one</span><span class="python_enclosure">(</span><span class="python_literal">'Preferences'</span><span class="python_operator">, </span><span class="python_name">colname</span><span class="python_operator">=</span><span class="python_literal">'pref_id'</span><span class="python_operator">, </span><span class="python_name">backref</span><span class="python_operator">=</span><span class="python_literal">'person'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
    <span class="python_operator"></span><span class="python_keyword">def </span><span class="python_name">__str__</span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_enclosure">)</span><span class="python_operator">:
        </span><span class="python_name">s </span><span class="python_operator">=  </span><span class="python_literal">'%s\n' </span><span class="python_operator">% </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">full_name</span><span class="python_operator">
        </span><span class="python_name">s </span><span class="python_operator">+= </span><span class="python_literal">'  * birthdate: %s\n' </span><span class="python_operator">% </span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">birth_date </span><span class="python_keyword">or </span><span class="python_literal">'not provided'</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">s </span><span class="python_operator">+= </span><span class="python_literal">'  * fave color: %s\n' </span><span class="python_operator">% </span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">preferences</span><span class="python_operator">.</span><span class="python_name">favorite_color </span><span class="python_keyword">or </span><span class="python_literal">'Unknown'</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">s </span><span class="python_operator">+= </span><span class="python_literal">'  * personality: %s\n' </span><span class="python_operator">% </span><span class="python_enclosure">(</span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">preferences</span><span class="python_operator">.</span><span class="python_name">personality_type </span><span class="python_keyword">or </span><span class="python_literal">'Unknown'</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
        <span class="python_keyword">for </span><span class="python_name">address </span><span class="python_keyword">in </span><span class="python_name">self</span><span class="python_operator">.</span><span class="python_name">addresses</span><span class="python_operator">:
            </span><span class="python_name">s </span><span class="python_operator">+= </span><span class="python_literal">'  * address: %s\n' </span><span class="python_operator">% </span><span class="python_name">address</span><span class="python_operator">.</span><span class="python_name">address_1</span><span class="python_operator">
            </span><span class="python_name">s </span><span class="python_operator">+= </span><span class="python_literal">'             %s, %s %s\n' </span><span class="python_operator">% </span><span class="python_enclosure">(</span><span class="python_name">address</span><span class="python_operator">.</span><span class="python_name">city</span><span class="python_operator">, </span><span class="python_name">address</span><span class="python_operator">.</span><span class="python_name">state</span><span class="python_operator">, </span><span class="python_name">address</span><span class="python_operator">.</span><span class="python_name">postal_code</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
        <span class="python_operator"></span><span class="python_keyword">return </span><span class="python_name">s</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Preferences</span><span class="python_enclosure">(</span><span class="python_name">ActiveMapper</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">class </span><span class="python_name">mapping</span><span class="python_operator">:
        </span><span class="python_name">__table__        </span><span class="python_operator">= </span><span class="python_literal">'preferences'</span><span class="python_operator">
        </span><span class="python_name">id               </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">favorite_color   </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">personality_type </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
</span>
<span class="python_operator"></span><span class="python_keyword">class </span><span class="python_name">Address</span><span class="python_enclosure">(</span><span class="python_name">ActiveMapper</span><span class="python_enclosure">)</span><span class="python_operator">:
    </span><span class="python_keyword">class </span><span class="python_name">mapping</span><span class="python_operator">:
        </span><span class="python_name">id          </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">primary_key</span><span class="python_operator">=</span><span class="python_name">True</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">type        </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">address_1   </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">city        </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">state       </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">postal_code </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">String</span><span class="python_enclosure">)</span><span class="python_operator">
        </span><span class="python_name">person_id   </span><span class="python_operator">= </span><span class="python_name">column</span><span class="python_enclosure">(</span><span class="python_name">Integer</span><span class="python_operator">, </span><span class="python_name">foreign_key</span><span class="python_operator">=</span><span class="python_name">ForeignKey</span><span class="python_enclosure">(</span><span class="python_literal">'person.id'</span><span class="python_enclosure">))</span><span class="python_operator">
</span></pre>
    </div>
<p>More discussion on ActiveMapper can be found at <a href='http://cleverdevil.org/computing/35/declarative-mapping-with-sqlalchemy'>Jonathan LaCour's Blog</a> as well as the <a href='http://www.sqlalchemy.org/trac/wiki/ActiveMapper'>SQLAlchemy Wiki</a>.
</p>




            <a href="#plugins" class="totoc">back to section top</a>
    </div>




    </div>




    </div>



    
    
    <A name="docstrings"></a>

    
    
    <A name="docstrings_sqlalchemy.engine"></a>

    
    
    <A name="docstrings_sqlalchemy.engine.default"></a>

    
    
    <A name="docstrings_sqlalchemy.engine.strategies"></a>

    
    
    <A name="docstrings_sqlalchemy.engine.threadlocal"></a>

    
    
    <A name="docstrings_sqlalchemy.engine.url"></a>

    
    
    <A name="docstrings_sqlalchemy.exceptions"></a>

    
    
    <A name="docstrings_sqlalchemy.interfaces"></a>

    
    
    <A name="docstrings_sqlalchemy.pool"></a>

    
    
    <A name="docstrings_sqlalchemy.schema"></a>

    
    
    <A name="docstrings_sqlalchemy.sql.compiler"></a>

    
    
    <A name="docstrings_sqlalchemy.sql.expression"></a>

    
    
    <A name="docstrings_sqlalchemy.types"></a>

    
    
    <A name="docstrings_sqlalchemy.orm"></a>

    
    
    <A name="docstrings_sqlalchemy.orm.collections"></a>

    
    
    <A name="docstrings_sqlalchemy.orm.interfaces"></a>

    
    
    <A name="docstrings_sqlalchemy.orm.mapper"></a>

    
    
    <A name="docstrings_sqlalchemy.orm.properties"></a>

    
    
    <A name="docstrings_sqlalchemy.orm.query"></a>

    
    
    <A name="docstrings_sqlalchemy.orm.session"></a>

    
    
    <A name="docstrings_sqlalchemy.orm.shard"></a>

    
    
    <A name="docstrings_sqlalchemy.ext.declarative"></a>

    
    
    <A name="docstrings_sqlalchemy.ext.associationproxy"></a>

    
    
    <A name="docstrings_sqlalchemy.ext.orderinglist"></a>

    
    
    <A name="docstrings_sqlalchemy.ext.sqlsoup"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.sqlite"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.postgres"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.mysql"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.oracle"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.mssql"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.firebird"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.sybase"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.access"></a>

    
    
    <A name="docstrings_sqlalchemy.databases.maxdb"></a>

    
    
    <A name="copyright"></a>

        
    <div class="navbanner">
        <a href="documentation.html" class="totoc">Table of Contents</a>
        
    <div class="prevnext">

            
            Previous: <a href="docstrings.html#docstrings">API Documentation</a>

    </div>

        <h2>Appendix:  Copyright</h2>
    </div>


        








    
    <A name="copyright"></a>
    
    <div class="sectionL1">

    
    

<p>This is the MIT license: http://www.opensource.org/licenses/mit-license.php
</p>
<p>Copyright (c) 2005, 2006, 2007, 2008 Michael Bayer and contributors. SQLAlchemy is a trademark of Michael
   Bayer.
</p>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this
   software and associated documentation files (the "Software"), to deal in the Software
   without restriction, including without limitation the rights to use, copy, modify, merge,
   publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
   to whom the Software is furnished to do so, subject to the following conditions:
</p>
<p>The above copyright notice and this permission notice shall be included in all copies or
   substantial portions of the Software.
</p>
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
   FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
</p>




            <a href="#copyright" class="totoc">back to section top</a>
    </div>










</body>
</html>






